package com.xbongbong.saas.service.impl;

import com.alibaba.dingtalk.openapi.newmessage.entity.OA;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.callback.help.ApiCallbackHelper;
import com.xbongbong.distributor.dto.DistributorContactEditAttrUpdateDTO;
import com.xbongbong.distributor.dto.DistributorContractOutStockEditAttrUpdateDTO;
import com.xbongbong.distributor.dto.DistributorEditAttrUpdateDTO;
import com.xbongbong.distributor.vo.DistributorEditAttrUpdateVO;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.help.log.UpdateBatchLogHelp;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.message.domain.entity.PushEntity;
import com.xbongbong.message.domain.entity.PushSetEntity;
import com.xbongbong.paas.abstracts.AbstractLowCodeExecuteService;
import com.xbongbong.paas.business.rule.FormDataActiveRuleByUpdateBatchHelp;
import com.xbongbong.paas.business.rule.FormDataInactiveRuleByDeleteBatchHelp;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.SizeConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.data.service.RichTextService;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.FundAccountFlowTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaySheetTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.enums.VisibleTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.VisibleRulePoJo;
import com.xbongbong.paas.help.BatchEditHelp;
import com.xbongbong.paas.help.BusinessUserTeamHelp;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.help.FormDataValidateDataHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.ProGetHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.help.ProUpdateHelp;
import com.xbongbong.paas.help.SharePermissionHelp;
import com.xbongbong.paas.help.WorkflowHelp;
import com.xbongbong.paas.help.team.FormTeamSetHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.entity.OperateLogEntity;
import com.xbongbong.paas.log.model.OperateLogModel;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.FineClueCompanyModel;
import com.xbongbong.paas.model.FineClueConsumptionModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.pojo.AttrValuePojo;
import com.xbongbong.paas.pojo.CreditCardBillInfoPojo;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.dto.AnalysisDataDTO;
import com.xbongbong.paas.pojo.dto.CoUserListDTO;
import com.xbongbong.paas.pojo.dto.CreditCardBillDTO;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataDeleteBatchDTO;
import com.xbongbong.paas.pojo.dto.FormDataRestoreDTO;
import com.xbongbong.paas.pojo.dto.FormDataThoroughDeleteDTO;
import com.xbongbong.paas.pojo.dto.FormDataUpdateBatchDTO;
import com.xbongbong.paas.pojo.dto.FormRichTextBatchDTO;
import com.xbongbong.paas.pojo.dto.InactiveRuleByDeleteBatchDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.vo.FormDataDeleteBatchVO;
import com.xbongbong.paas.pojo.vo.FormDataThoroughDeleteVO;
import com.xbongbong.paas.pojo.vo.FormDataUpdateBatchVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.pojo.vo.SetPaymentBatchVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import com.xbongbong.paas.service.ClueRuleService;
import com.xbongbong.paas.service.CoUserService;
import com.xbongbong.paas.service.CustomerRuleService;
import com.xbongbong.paas.service.FineClueService;
import com.xbongbong.paas.service.MarketingManagementService;
import com.xbongbong.paas.service.PaasFormDataService;
import com.xbongbong.paas.service.PaasFormExplainService;
import com.xbongbong.paas.service.ProFormDataService;
import com.xbongbong.paas.service.TransferBackRuleScriptService;
import com.xbongbong.paas.service.dynamic.crm.strategy.CustomerDynamicStrategy;
import com.xbongbong.paas.service.dynamic.crm.strategy.DynamicStrategyFactory;
import com.xbongbong.paas.service.dynamic.crm.strategy.MainBusinessDynamicStrategy;
import com.xbongbong.paas.service.dynamic.crm.strategy.PushNotifyDynamicStrategy;
import com.xbongbong.paas.service.dynamic.help.DynamicHelp;
import com.xbongbong.paas.service.log.crm.help.OperationLogHelp;
import com.xbongbong.paas.service.log.crm.operation.CompetitorOperationLogHandle;
import com.xbongbong.paas.service.log.crm.operation.CustomerOperationLogHandle;
import com.xbongbong.paas.service.team.TeamDataHelp;
import com.xbongbong.paas.service.workflow.trigger.WorkflowFormDataOperationService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.thread.TransmittableThreadLocalUtil;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CloneUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.RegexUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.CancelRestoreBaseVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.ItemUtil;
import com.xbongbong.parent.factory.BusinessBatchFactory;
import com.xbongbong.parent.help.CommonPermissionHelp;
import com.xbongbong.parent.interfaces.BusinessBatchEditService;
import com.xbongbong.parent.interfaces.logger.ArchiveOperationLogHandle;
import com.xbongbong.parent.interfaces.logger.OperationLogFactory;
import com.xbongbong.parent.interfaces.logger.PushNotifyLogHandle;
import com.xbongbong.pro.api.pojo.DataInfoDTO;
import com.xbongbong.pro.assemble.pojo.dto.AssembleEditAttrUpdateDTO;
import com.xbongbong.pro.bom.pojo.dto.BomEditAttrUpdateDTO;
import com.xbongbong.pro.businessdata.pojo.FollowPojo;
import com.xbongbong.pro.businessdata.pojo.dto.FocusDTO;
import com.xbongbong.pro.businessdata.pojo.vo.FollowVO;
import com.xbongbong.pro.businessrule.pojo.dto.ActiveRuleByUpdateBatchDTO;
import com.xbongbong.pro.competitor.pojo.dto.CompetitorEditAttrUpdateDTO;
import com.xbongbong.pro.competitor.pojo.dto.log.CompetitorPortionVisibleLogDTO;
import com.xbongbong.pro.competitor.pojo.dto.log.CompetitorRemoveVisibleLogDTO;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.contact.pojo.dto.ContactEditAttrUpdateDTO;
import com.xbongbong.pro.contract.pojo.dto.ContractEditAttrUpdateDTO;
import com.xbongbong.pro.contract.pojo.vo.ContractEditAttrUpdateVO;
import com.xbongbong.pro.costadjust.dto.CostAdjustEditAttrUpdateDTO;
import com.xbongbong.pro.customer.pojo.dto.CustomerEditAttrUpdateDTO;
import com.xbongbong.pro.customer.pojo.dto.CustomerRestoreBatchDTO;
import com.xbongbong.pro.customer.pojo.vo.CustomerEditAttrUpdateVO;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerDynamicAddDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.DynamicDTO;
import com.xbongbong.pro.detailtab.dto.DetailCommunicateDTO;
import com.xbongbong.pro.domain.entity.FineClueCompanyEntity;
import com.xbongbong.pro.domain.entity.FormTeamSetEntity;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.domain.entity.UpdateDataValueEntity;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicArchiveDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicBackDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicCheckJoinTeamDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicDistributeDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicGrapDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicPushNotifyDeleteDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicRestoreDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicUpdateBatchDTO;
import com.xbongbong.pro.enums.CommunicatePlanNotifyTypeEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.EditFieldTypeEnum;
import com.xbongbong.pro.enums.ListBatchResultEnum;
import com.xbongbong.pro.enums.PackageStatusEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.UpdateCustomerTeamScenesEnum;
import com.xbongbong.pro.enums.ValueAddedTypeEnum;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.BusinessTypeErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ContractErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.CreditManagement;
import com.xbongbong.pro.enums.errorcodes.FundAccountErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.InvoiceErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.OutstockErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.PaymentErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ProErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ProductErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SettleAccountErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SharePermissionErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.UserTeamErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.WorkOrderErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.enums.lowcode.LowCodeExecuteServiceEnum;
import com.xbongbong.pro.enums.menu.enums.FineClueComboEnum;
import com.xbongbong.pro.enums.menu.enums.FineClueStatusEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormDefaultPatternEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormPatternEnum;
import com.xbongbong.pro.fineclue.pojo.dto.FineClueClueReleaseDTO;
import com.xbongbong.pro.form.pojo.dto.ChildProductDTO;
import com.xbongbong.pro.formdata.pojo.dto.FormDataDetailDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.dto.LinkKeyExplainListDTO;
import com.xbongbong.pro.formexplain.pojo.vo.LinkKeyExplainListVO;
import com.xbongbong.pro.fundtransfer.pojo.FundTransferEditAttrUpdateDTO;
import com.xbongbong.pro.instock.pojo.dto.InstockEditAttrUpdateDTO;
import com.xbongbong.pro.inventory.pojo.dto.InventoryEditAttrUpdateDTO;
import com.xbongbong.pro.invoice.pojo.InvoiceCancelOrRestorePojo;
import com.xbongbong.pro.invoice.pojo.dto.InvoiceEditAttrUpdateDTO;
import com.xbongbong.pro.label.pojo.vo.LabelBatchMessageVO;
import com.xbongbong.pro.listbatch.pojo.ErrorMessagePojo;
import com.xbongbong.pro.listbatch.pojo.TeamBatchPojo;
import com.xbongbong.pro.listbatch.pojo.dto.AddCoUserDTO;
import com.xbongbong.pro.listbatch.pojo.dto.AddLabelDTO;
import com.xbongbong.pro.listbatch.pojo.dto.AddMainUserDTO;
import com.xbongbong.pro.listbatch.pojo.dto.ArchiveDTO;
import com.xbongbong.pro.listbatch.pojo.dto.CancelDTO;
import com.xbongbong.pro.listbatch.pojo.dto.ChangeMainDTO;
import com.xbongbong.pro.listbatch.pojo.dto.CreditFreezeDTO;
import com.xbongbong.pro.listbatch.pojo.dto.CreditRevokeDTO;
import com.xbongbong.pro.listbatch.pojo.dto.DelCoUserDTO;
import com.xbongbong.pro.listbatch.pojo.dto.DelMainUserDTO;
import com.xbongbong.pro.listbatch.pojo.dto.DelRemindDTO;
import com.xbongbong.pro.listbatch.pojo.dto.DistributionDTO;
import com.xbongbong.pro.listbatch.pojo.dto.IsolationAddCoUserDTO;
import com.xbongbong.pro.listbatch.pojo.dto.IsolationCreateTeamDTO;
import com.xbongbong.pro.listbatch.pojo.dto.IsolationDelCoUserDTO;
import com.xbongbong.pro.listbatch.pojo.dto.IsolationDisbandTeamDTO;
import com.xbongbong.pro.listbatch.pojo.dto.ListBatchDTO;
import com.xbongbong.pro.listbatch.pojo.dto.OnlineDTO;
import com.xbongbong.pro.listbatch.pojo.dto.PortionCompetitorDepDTO;
import com.xbongbong.pro.listbatch.pojo.dto.PortionCompetitorUserDTO;
import com.xbongbong.pro.listbatch.pojo.dto.PortionDepDTO;
import com.xbongbong.pro.listbatch.pojo.dto.PortionMoveCompetitorDepDTO;
import com.xbongbong.pro.listbatch.pojo.dto.PortionMoveCompetitorUserDTO;
import com.xbongbong.pro.listbatch.pojo.dto.PortionMoveDepDTO;
import com.xbongbong.pro.listbatch.pojo.dto.PortionMoveUserDTO;
import com.xbongbong.pro.listbatch.pojo.dto.PortionUserDTO;
import com.xbongbong.pro.listbatch.pojo.dto.ProductionStatusDTO;
import com.xbongbong.pro.listbatch.pojo.dto.RemindDTO;
import com.xbongbong.pro.listbatch.pojo.dto.RemoveLableDTO;
import com.xbongbong.pro.listbatch.pojo.dto.StatusChangeDTO;
import com.xbongbong.pro.listbatch.pojo.dto.UpdatePublicGroupDTO;
import com.xbongbong.pro.listbatch.pojo.dto.UpdateRemindDTO;
import com.xbongbong.pro.listbatch.pojo.vo.RemindVO;
import com.xbongbong.pro.listbatch.pojo.vo.TeamBatchVO;
import com.xbongbong.pro.log.pojo.dto.BackToPublicDTO;
import com.xbongbong.pro.log.pojo.dto.CustomerGrabLogDTO;
import com.xbongbong.pro.log.pojo.dto.RevertLogDTO;
import com.xbongbong.pro.log.pojo.dto.ThoroughDeleteLogDTO;
import com.xbongbong.pro.lowcodeexecute.pojo.dto.LowCodeExecuteServiceDTO;
import com.xbongbong.pro.marketManage.pojo.dto.MarketActivityEditAttrUpdateDTO;
import com.xbongbong.pro.message.constant.CluePushConstant;
import com.xbongbong.pro.message.constant.CustomerPushConstant;
import com.xbongbong.pro.message.constant.DistributorPushConstant;
import com.xbongbong.pro.message.constant.InvoicePushConstant;
import com.xbongbong.pro.message.enums.PushObjectTypeEnum;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.model.PushLinkModel;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.message.model.PushSetModel;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.message.pushset.CluePushSet;
import com.xbongbong.pro.message.pushset.CustomerPushSet;
import com.xbongbong.pro.message.service.MessageService;
import com.xbongbong.pro.opportunity.pojo.dto.OpportunityEditAttrUpdateDTO;
import com.xbongbong.pro.otherexpense.pojo.dto.OtherExpenseEditAttrUpdateDTO;
import com.xbongbong.pro.otherincome.pojo.dto.OtherIncomeEditAttrUpdateDTO;
import com.xbongbong.pro.outstock.pojo.dto.OutStockListDTO;
import com.xbongbong.pro.outstock.pojo.dto.OutstockEditAttrUpdateDTO;
import com.xbongbong.pro.outstock.pojo.vo.OutStockListVO;
import com.xbongbong.pro.payment.pojo.dto.PaymentEditAttrUpdateDTO;
import com.xbongbong.pro.paymentsheet.pojo.dto.PaymentSheetEditAttrUpdateDTO;
import com.xbongbong.pro.payplan.pojo.dto.PayPlanEditAttrUpdateDTO;
import com.xbongbong.pro.payplansheet.pojo.dto.PaySheetEditAttrUpdateDTO;
import com.xbongbong.pro.permission.pojo.dto.VerifyDeletePermissionDTO;
import com.xbongbong.pro.permission.pojo.dto.VerifyUpdatePermissionDTO;
import com.xbongbong.pro.product.pojo.dto.ProductEditAttrUpdateDTO;
import com.xbongbong.pro.productionorder.pojo.dto.ProductionOrderEditAttrUpdateDTO;
import com.xbongbong.pro.purchase.pojo.dto.PurchaseEditAttrUpdateDTO;
import com.xbongbong.pro.purchaseinvoice.dto.PurchaseInvoiceEditAttrUpdateDTO;
import com.xbongbong.pro.purchaseinvoice.pojo.PurchaseInvoiceCancelOrRestorePojo;
import com.xbongbong.pro.quatation.pojo.dto.QuotationEditAttrUpdateDTO;
import com.xbongbong.pro.rabbitmq.producer.BaseProducer;
import com.xbongbong.pro.refund.pojo.dto.RefundEditAttrUpdateDTO;
import com.xbongbong.pro.returned.pojo.dto.ReturnEditAttrUpdateDTO;
import com.xbongbong.pro.returnedpurchase.pojo.dto.ReturnedPurchaseEditAttrUpdateDTO;
import com.xbongbong.pro.service.toolbox.statistic.help.TeamHelp;
import com.xbongbong.pro.supplier.pojo.dto.SupplierEditAttrUpdateDTO;
import com.xbongbong.pro.suppliercontact.pojo.dto.SupplierContactEditAttrUpdateDTO;
import com.xbongbong.pro.team.TeamAfterVerifyDTO;
import com.xbongbong.pro.team.TeamUpdateMidPOJO;
import com.xbongbong.pro.team.TeamVerifyDTO;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.pro.transfer.pojo.dto.TransferEditAttrUpdateDTO;
import com.xbongbong.pro.warehouse.pojo.dto.WareHouseEditAttrUpdateDTO;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.pro.workorder.pojo.dto.WorkOrderEditAttrUpdateDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.ListBatchConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.teammembers.TeamMembersConstant;
import com.xbongbong.saas.domain.entity.ClueRuleEntity;
import com.xbongbong.saas.domain.entity.CustomerRuleEntity;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.domain.entity.DistributorAccountEntity;
import com.xbongbong.saas.domain.entity.FundAccountEntity;
import com.xbongbong.saas.domain.entity.FundAccountFlowEntity;
import com.xbongbong.saas.domain.entity.InvoiceRelationshipEntity;
import com.xbongbong.saas.domain.entity.ProductUserEntity;
import com.xbongbong.saas.domain.entity.PublicGroupSeniorEntity;
import com.xbongbong.saas.domain.entity.PurchaseInvoiceRelationshipEntity;
import com.xbongbong.saas.domain.entity.SettleAccountsEntity;
import com.xbongbong.saas.domain.entity.ShareRuleEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.domain.entity.competitor.CompetitorUserEntity;
import com.xbongbong.saas.domain.entity.ext.ClueEntityExt;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.InvoiceEntityExt;
import com.xbongbong.saas.domain.entity.ext.OpportunityEntityExt;
import com.xbongbong.saas.domain.entity.ext.PayPlanSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.domain.entity.ext.ProductionOrderEntityExt;
import com.xbongbong.saas.domain.entity.ext.PurchaseInvoiceEntityExt;
import com.xbongbong.saas.domain.entity.ext.QuotationEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderFormEntityExt;
import com.xbongbong.saas.enums.ClueRuleEnum;
import com.xbongbong.saas.enums.CreditCardBillTypeEnum;
import com.xbongbong.saas.enums.CustomerRuleEnum;
import com.xbongbong.saas.enums.CustomerStatementStatisticDistributorEnum;
import com.xbongbong.saas.enums.CustomerStatementStatisticEnum;
import com.xbongbong.saas.enums.CustomerStatementStatusEnum;
import com.xbongbong.saas.enums.ExecutorCheckBoxEnum;
import com.xbongbong.saas.enums.InstockTypeEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.TagTypeEnum;
import com.xbongbong.saas.enums.TimeIntervalTypeEnum;
import com.xbongbong.saas.enums.UserTeamEnum;
import com.xbongbong.saas.enums.UserTeamOperateTagEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.base.ManagementBaseEnum;
import com.xbongbong.saas.enums.business.AssembleEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CreditLimitEnum;
import com.xbongbong.saas.enums.business.CreditTemporaryLimitEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.DistributorEnum;
import com.xbongbong.saas.enums.business.ExternalDataSourceEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.OrderEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.PayPlanEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetDistributorEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.ProductionOrderEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.PurchaseInvoiceEnum;
import com.xbongbong.saas.enums.business.PushNotifyEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.WaitOutStockStatusEnum;
import com.xbongbong.saas.enums.dictionary.ArchivedEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.enums.dictionary.IsCancelEnum;
import com.xbongbong.saas.enums.dictionary.PayPlanStatusEnum;
import com.xbongbong.saas.enums.dictionary.PaymentStatusEnum;
import com.xbongbong.saas.enums.dictionary.ProductionOrderStatusEnum;
import com.xbongbong.saas.enums.dictionary.PublicEnum;
import com.xbongbong.saas.enums.dictionary.ShipStatusEnum;
import com.xbongbong.saas.help.DetailTabDataPermissionHelp;
import com.xbongbong.saas.help.FundHelp;
import com.xbongbong.saas.help.PublicSeniorLogHelp;
import com.xbongbong.saas.help.PublicSeniorRuleHelp;
import com.xbongbong.saas.help.SaasCreditHelper;
import com.xbongbong.saas.help.SaasCustomerHelp;
import com.xbongbong.saas.help.SaasCustomerStatementHelper;
import com.xbongbong.saas.help.SaasDataInitHelp;
import com.xbongbong.saas.help.SaasDeleteHelp;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.help.ScoreCalculateHelp;
import com.xbongbong.saas.help.ShowFormatHelp;
import com.xbongbong.saas.help.workflow.MarketActivityForStaticHelp;
import com.xbongbong.saas.model.ClueModel;
import com.xbongbong.saas.model.ClueUserModel;
import com.xbongbong.saas.model.CompetitorUserModel;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.CustomerFocusModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.DistributorAccountModel;
import com.xbongbong.saas.model.FundAccountFlowModel;
import com.xbongbong.saas.model.FundAccountModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.InvoiceRelationshipModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.saas.model.PaasFormDataModel;
import com.xbongbong.saas.model.PayPlanModel;
import com.xbongbong.saas.model.PayPlanSheetModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.model.PaymentSheetModel;
import com.xbongbong.saas.model.ProductUserModel;
import com.xbongbong.saas.model.ProductionOrderModel;
import com.xbongbong.saas.model.PublicGroupSeniorModel;
import com.xbongbong.saas.model.PurchaseInvoiceRelationshipModel;
import com.xbongbong.saas.model.PurchaseModel;
import com.xbongbong.saas.model.QuotationModel;
import com.xbongbong.saas.model.RefundInvoiceModel;
import com.xbongbong.saas.model.RefundModel;
import com.xbongbong.saas.model.ReturnedPurchaseInvoiceModel;
import com.xbongbong.saas.model.ReturnedPurchaseModel;
import com.xbongbong.saas.model.SettleAccountsModel;
import com.xbongbong.saas.model.TagLinkModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.model.WorkOrderModel;
import com.xbongbong.saas.service.AssembleService;
import com.xbongbong.saas.service.BomBillService;
import com.xbongbong.saas.service.ClueService;
import com.xbongbong.saas.service.CompetitorService;
import com.xbongbong.saas.service.ContactService;
import com.xbongbong.saas.service.ContractService;
import com.xbongbong.saas.service.CostAdjustService;
import com.xbongbong.saas.service.CustomerCommunicateService;
import com.xbongbong.saas.service.DistributorAccountService;
import com.xbongbong.saas.service.DistributorCommunicateService;
import com.xbongbong.saas.service.DistributorContactService;
import com.xbongbong.saas.service.DistributorManageService;
import com.xbongbong.saas.service.FundAccountService;
import com.xbongbong.saas.service.FundTransferService;
import com.xbongbong.saas.service.InstockService;
import com.xbongbong.saas.service.InventoryService;
import com.xbongbong.saas.service.InvoiceService;
import com.xbongbong.saas.service.ListBatchService;
import com.xbongbong.saas.service.MarketActivityService;
import com.xbongbong.saas.service.OpportunityService;
import com.xbongbong.saas.service.OrderOutstockService;
import com.xbongbong.saas.service.OtherExpenseService;
import com.xbongbong.saas.service.OtherIncomeService;
import com.xbongbong.saas.service.OutstockService;
import com.xbongbong.saas.service.PayPlanService;
import com.xbongbong.saas.service.PayPlanSheetService;
import com.xbongbong.saas.service.PaymentService;
import com.xbongbong.saas.service.PaymentSheetService;
import com.xbongbong.saas.service.ProductService;
import com.xbongbong.saas.service.ProductionOrderService;
import com.xbongbong.saas.service.PublicGroupSeniorService;
import com.xbongbong.saas.service.PurchaseInvoiceService;
import com.xbongbong.saas.service.PurchaseService;
import com.xbongbong.saas.service.QuotationService;
import com.xbongbong.saas.service.RefundService;
import com.xbongbong.saas.service.ReturnService;
import com.xbongbong.saas.service.ReturnedPurchaseService;
import com.xbongbong.saas.service.ScoreCalculateService;
import com.xbongbong.saas.service.SupplierContactService;
import com.xbongbong.saas.service.SupplierService;
import com.xbongbong.saas.service.TransferService;
import com.xbongbong.saas.service.UserTeamService;
import com.xbongbong.saas.service.WarehouseService;
import com.xbongbong.saas.service.WorkOrderService;
import com.xbongbong.saas.service.toolbox.help.FundSetHelp;
import com.xbongbong.saas.service.toolbox.help.PackageStatusHelp;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.DataPermissionEnum;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import com.xbongbong.workflow.model.impl.WorkflowModelImpl;
import joptsimple.internal.Strings;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleOrDefaultFromFormData;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author haibin.zhang
 * @version v1.0
 * @date 2019/2/20 22:50
 * @since v1.0
 */
@Service("listBatchService")
public class ListBatchServiceImpl implements ListBatchService {

    private static final Logger LOG = LoggerFactory.getLogger(ListBatchServiceImpl.class);

    @Resource
    private ProGetHelp proGetHelp;
    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private UserModel userModel;
    @Resource
    private UserTeamService userTeamService;
    @Resource
    private CustomerFocusModel customerFocusModel;
    @Resource
    private CustomerServiceImpl customerService;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private ProductUserModel productUserModel;
    @Resource
    private SaasDeleteHelp saasDeleteHelp;
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private ShowFormatHelp showFormatHelp;
    @Resource
    private PaasFormDataModel paasFormDataModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private OperateLogModel operateLogModel;
    @Resource
    private OpportunityService opportunityService;
    @Resource
    private PaymentSheetModel paymentSheetModel;
    @Resource
    private DataDictionaryModel dataDictionaryModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private PaymentModel paymentModel;
    @Resource
    private CustomerRuleService customerRuleService;
    @Resource
    private EsHelper esHelper;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private FormDataValidateDataHelp formDataValidateDataHelp;
    @Resource
    private PaasFormDataService paasFormDataService;
    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private PushModel pushModel;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private BaseProducer baseProducer;
    @Resource
    private MessageService messageService;
    @Resource
    private InvoiceRelationshipModel invoiceRelationshipModel;
    @Resource
    private InvoiceService invoiceService;
    @Resource
    private RefundInvoiceModel refundInvoiceModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private FormDataInactiveRuleByDeleteBatchHelp formDataInactiveRuleByDeleteBatchHelp;
    @Resource
    private FormDataActiveRuleByUpdateBatchHelp formDataActiveRuleByUpdateBatchHelp;
    @Resource
    private PushSetModel pushSetModel;
    @Resource
    private PushLinkModel pushLinkModel;
    @Resource
    @Lazy
    private CustomerCommunicateService customerCommunicateService;
    @Resource
    private CoUserService coUserService;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private ProFormDataService proFormDataService;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private QuotationModel quotationModel;
    @Resource
    private WorkOrderModel workOrderModel;
    @Resource
    private ContactService contactService;
    @Resource
    @Lazy
    private ApiCallbackHelper apiCallbackHelper;
    @Resource
    private QuotationService quotationService;
    @Resource
    private RefundModel refundModel;
    @Resource
    private OutstockService outstockService;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private PurchaseInvoiceRelationshipModel purchaseInvoiceRelationshipModel;
    @Resource
    private PayPlanSheetModel paySheetModel;
    @Resource
    private PurchaseInvoiceService purchaseInvoiceService;
    @Resource
    private ReturnedPurchaseModel returnedPurchaseModel;
    @Resource
    private ReturnedPurchaseInvoiceModel returnedPurchaseInvoiceModel;
    @Resource
    private PurchaseModel purchaseModel;
    @Resource
    private PayPlanModel payPlanModel;
    @Resource
    private FundAccountModel fundAccountModel;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private FundAccountService fundAccountService;
    @Resource
    private FundAccountFlowModel fundAccountFlowModel;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private ProUpdateHelp proUpdateHelp;
    @Resource
    private PaymentService paymentService;
    @Resource
    private MarketingManagementService marketingManagementService;
    @Resource
    private DistributorAccountModel distributorAccountModel;
    @Resource
    private DistributorCommunicateService distributorCommunicateService;
    @Resource
    private PaasFormExplainService paasFormExplainService;
    @Resource
    private ClueUserModel clueUserModel;
    @Resource
    private ClueModel clueModel;
    @Resource
    private ClueRuleService clueRuleService;
    @Resource
    private AbstractLowCodeExecuteService abstractLowCodeExecuteService;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private DistributorAccountService distributorAccountService;
    @Resource
    private WorkflowFormDataOperationService workflowFormDataOperationService;
    @Resource
    private SaasCustomerStatementHelper saasCustomerStatementHelper;
    @Resource
    private SaasCreditHelper saasCreditHelper;
    @Resource
    private PackageStatusHelp packageStatusHelp;
    @Resource
    private BomBillService bomBillService;
    @Resource
    private ProductService productService;
    @Resource
    private ContractService contractService;
    @Resource
    private InstockService instockService;
    @Resource
    private SupplierService supplierService;
    @Resource
    private ProductionOrderService productionOrderService;
    @Resource
    private InventoryService inventoryService;
    @Resource
    private PurchaseService purchaseService;
    @Resource
    private ReturnedPurchaseService returnedPurchaseService;
    @Resource
    private TransferService transferService;
    @Resource
    private AssembleService assembleService;
    @Resource
    private PayPlanService payPlanService;
    @Resource
    private SupplierContactService supplierContactService;
    @Resource
    private PaymentSheetService paymentSheetService;
    @Resource
    private PayPlanSheetService payPlanSheetService;
    @Resource
    private RefundService refundService;
    @Resource
    private WorkOrderService workOrderService;
    @Resource
    private MarketActivityService marketActivityService;
    @Resource
    private ClueService clueService;
    @Resource
    private ScoreCalculateHelp scoreCalculateHelp;
    @Resource
    private DistributorContactService distributorContactService;
    @Resource
    private DistributorManageService distributorManageService;
    @Resource
    private ScoreCalculateService scoreCalculateService;
    @Resource
    private WarehouseService warehouseService;
    @Resource
    private OrderOutstockService orderOutstockService;
    @Resource
    private ReturnService returnService;
    @Resource
    private OtherIncomeService otherIncomeService;
    @Resource
    private OtherExpenseService otherExpenseService;
    @Resource
    private FundTransferService fundTransferService;
    @Resource
    private WorkflowHelp workflowHelp;
    @Resource
    private CostAdjustService costAdjustService;
    @Resource
    private SettleAccountsModel settleAccountsModel;
    @Resource
    private ProductionOrderModel productionOrderModel;
    @Resource
    private FineClueCompanyModel fineClueCompanyModel;
    @Resource
    private FineClueConsumptionModel fineClueConsumptionModel;
    @Resource
    private FineClueService fineClueService;
    @Resource
    private MarketActivityForStaticHelp marketActivityForStaticHelp;
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private TeamDataHelp teamDataHelp;
    @Resource
    private SaasCustomerHelp saasCustomerHelp;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private DetailTabDataPermissionHelp detailTabDataPermissionHelp;
    @Resource
    private FormTeamSetHelp formTeamSetHelp;
    @Resource
    private PublicGroupSeniorModel publicGroupSeniorModel;
    @Resource
    private PublicSeniorLogHelp publicSeniorLogHelp;
    @Resource
    private PublicGroupSeniorService publicGroupSeniorService;
    @Resource
    private TagLinkModel tagLinkModel;
    @Resource
    private PublicSeniorRuleHelp publicSeniorRuleHelp;
    @Resource
    private TransferBackRuleScriptService transferBackRuleScriptService;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private OperationLogHelp operationLogHelp;
    @Resource
    private OperationLogFactory operationLogFactory;
    @Resource
    private CustomerOperationLogHandle customerOperationLogHandle;
    @Resource
    private DynamicStrategyFactory dynamicStrategyFactory;
    @Resource
    private DynamicHelp dynamicHelp;
    @Resource
    private WorkflowModelImpl workflowModel;
    @Resource
    private RichTextService richTextService;
    @Resource
    private BatchEditHelp batchEditHelp;
    @Resource
    private BusinessBatchFactory businessBatchFactory;
    @Resource
    private CompetitorService competitorService;
    @Resource
    private CompetitorUserModel competitorUserModel;
    @Resource
    private TeamHelp teamHelp;
    @Resource
    private UpdateBatchLogHelp updateBatchLogHelp;
    @Resource
    private BusinessUserTeamHelp businessUserTeamHelp;
    @Resource
    private CommonPermissionHelp commonPermissionHelp;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private SharePermissionHelp sharePermissionHelp;

    @Override
    public BaseVO archive(ArchiveDTO archiveDTO) throws XbbException {
        Integer businessType = archiveDTO.getBusinessType();
        Integer distributorMark = archiveDTO.getDistributorMark();
        businessType = XbbRefTypeEnum.transferBusinessType4Distributor(businessType,distributorMark);
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
        businessType = XbbRefTypeEnum.transferBusinessType2Index(businessType);
        String attr;
        UserVO loginUser = archiveDTO.getLoginUser();
        Set<String> permSet = loginUser.getPermSet();
        String corpid = archiveDTO.getCorpid();
        String userId = archiveDTO.getUserId();
        Integer archived = archiveDTO.getArchived();
        List<Long> dataIdList = archiveDTO.getDataIdList();
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, businessType, SaasMarkEnum.SAAS.getCode());
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = paasEsModel.getByIdList(dataIdList, corpid, SaasMarkEnum.SAAS.getCode(), businessType, new ArrayList<>(), indexTypeEnum);
        Map<Long, List<String>> ownerIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        businessUserTeamHelp.getUserIdMapSetShow(new HashSet<>(), dataIdList, corpid, businessType, false, ownerIdMap, coUserIdMap, DelEnum.NORMAL.getDel());
        List<String> paasName = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        OperateModuleTypeEnum operateModuleType;
        boolean isSingle = Objects.equals(archiveDTO.getIsBatch(), BasicConstant.ZERO);
        boolean hasDataPermission = true;
        if (isSingle){
            //单条操作,团队权限可见或共享权限可编辑
            PaasFormDataEntityExt paasFormDataEntityExt = paasFormDataEntityExtList.get(0);
            paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
            paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
            VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
            hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
        }else{
            List<Long> errorDataIdList = new ArrayList<>();
            //数据库获取相关规则
            List<ShareRuleEntity> ruleEntities = sharePermissionHelp.getRuleEntities(corpid, archiveDTO.getFormId(), loginUser.getUserId());
            for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
                paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
                paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
                VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
                hasDataPermission = commonPermissionHelp.checkPermission(verifyUpdatePermissionDTO);
                if(!hasDataPermission){
                    verifyUpdatePermissionDTO.setRuleEntities(ruleEntities);
                    hasDataPermission = sharePermissionHelp.verifySharePermission4EditWithRuleEngine(verifyUpdatePermissionDTO);
                }
                if (!hasDataPermission){
                    errorDataIdList.add(paasFormDataEntityExt.getId());
                }
            }
            if(CollectionUtils.isNotEmpty(errorDataIdList)){
                dataIdList.removeIf(errorDataIdList :: contains);
            }
        }
        if(CollectionUtils.isEmpty(dataIdList)){
            return new BaseVO();
        }
        switch (redundantTemplateTypeEnum){
            case CUSTOMER:
                if (!permSet.contains(ProPermissionAliasEnum.CUSTOMER_ARICHIVE.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CUSTOMER_ARICHIVE.getMemo()));
                }
                if (isSingle && !hasDataPermission){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CUSTOMER_ARICHIVE.getMemo()));
                }
                attr = CustomerManagementEnum.IS_ARCHIVED.getAttr();
                operateModuleType = OperateModuleTypeEnum.CUSTOMER;
                for(PaasFormDataEntityExt getName : paasFormDataEntityExtList){
                    JSONObject data = getName.getData();
                    paasName.add(FastJsonHelper.getStringOrDefaultFromFormData(data, CustomerManagementEnum.NAME.getAttr(), ""));
                }
                break;
            case CONTRACT:
                if (!permSet.contains(ProPermissionAliasEnum.CONTRACT_ARCHIVE.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CONTRACT_ARCHIVE.getMemo()));
                }
                if (isSingle && !hasDataPermission){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CONTRACT_ARCHIVE.getMemo()));
                }
                attr = ContractEnum.ARCHIVED.getAttr();
                operateModuleType = OperateModuleTypeEnum.CONTRACT;
                for(PaasFormDataEntityExt getName : paasFormDataEntityExtList){
                    JSONObject data = getName.getData();
                    String serialNo = getName.getSerialNo();
                    String contractName = data.getString(ContractEnum.NAME.getAttr());
                    contractName = contractName == null ? serialNo : new StringBuilder().append(serialNo).append("（").append(contractName).append("）").toString();
                    paasName.add(contractName);
                }
                //同步归档状态到关联产品表
                if (Objects.equals(archived,ArchivedEnum.ARCHIVED.getCode())){
                    contractProductModel.updateWaitOutStatusById(dataIdList,corpid, WaitOutStockStatusEnum.UNUSUAL.getCode(),BasicConstant.THREE);
                }else if(Objects.equals(archived,ArchivedEnum.UN_ARCHIVED.getCode())){
                    //获取合同出库状态
                    List<Long> contractIds = new ArrayList<>();
                    for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
                        JSONObject data = paasFormDataEntityExt.getData();
                        if (!Objects.equals(data.get(ContractEnum.SHIP_STATUS.getAttr()), ShipStatusEnum.CLOSED.getCode())) {
                            //出库状态不为关闭的合同才去更新状态
                            contractIds.add(paasFormDataEntityExt.getId());
                        }
                    }
                    if (!contractIds.isEmpty()){
                        contractProductModel.updateWaitOutStatusById(contractIds, corpid, WaitOutStockStatusEnum.NORMAL.getCode(), WaitOutStockStatusEnum.NORMAL.getCode());
                    }
                }
                break;
            case ORDER:
                if (!permSet.contains(ProPermissionAliasEnum.ORDER_EDIT.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.ORDER_EDIT.getMemo()));
                }
                if (isSingle && !hasDataPermission){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.ORDER_EDIT.getMemo()));
                }
                attr = ContractEnum.ARCHIVED.getAttr();
                operateModuleType = OperateModuleTypeEnum.CONTRACT;
                for(PaasFormDataEntityExt getName : paasFormDataEntityExtList){
                    String orderSerial = getName.getSerialNo();
                    JSONObject data = getName.getData();
                    Integer orderStatus = FastJsonHelper.getIntegerOrDefaultFromFormData(data, OrderEnum.STATUS.getAttr(), BasicConstant.ONE);
                    //订单状态为待订单审核或者待财务审核的 不支持归档
                    if (Objects.equals(BasicConstant.ONE,orderStatus) || Objects.equals(BasicConstant.TWO,orderStatus)){
                        throw new XbbException(ContractErrorCodeEnum.API_ERROR_203021.getCode(), String.format(ContractErrorCodeEnum.API_ERROR_203021.getMsg(),orderSerial));
                    }
                    String serialNo = getName.getSerialNo();
                    String contractName = data.getString(ContractEnum.NAME.getAttr());
                    contractName = contractName == null ? serialNo : new StringBuilder().append(serialNo).append("（").append(contractName).append("）").toString();
                    paasName.add(contractName);
                }
                //同步归档状态到关联产品表
                if (Objects.equals(archived, ArchivedEnum.ARCHIVED.getCode())) {
                    contractProductModel.updateWaitOutStatusById(dataIdList, corpid, WaitOutStockStatusEnum.UNUSUAL.getCode(), BasicConstant.THREE);
                } else if (Objects.equals(archived, ArchivedEnum.UN_ARCHIVED.getCode())) {
                    //获取合同出库状态
                    List<Long> contractIds = new ArrayList<>();
                    for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
                        JSONObject data = paasFormDataEntityExt.getData();
                        if (!Objects.equals(data.get(ContractEnum.SHIP_STATUS.getAttr()), ShipStatusEnum.CLOSED.getCode())) {
                            //出库状态不为关闭的合同才去更新状态
                            contractIds.add(paasFormDataEntityExt.getId());
                        }
                    }
                    if (!contractIds.isEmpty()) {
                        contractProductModel.updateWaitOutStatusById(contractIds, corpid, WaitOutStockStatusEnum.NORMAL.getCode(), WaitOutStockStatusEnum.NORMAL.getCode());
                    }
                }
                break;
            case SALES_OPPORTUNITY:
                if (!permSet.contains(ProPermissionAliasEnum.OPPORTUNITY_ARCHIVE.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.OPPORTUNITY_ARCHIVE.getMemo()));
                }
                if (isSingle && !hasDataPermission){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.OPPORTUNITY_ARCHIVE.getMemo()));
                }
                attr = SalesOpportunityEnum.IS_ARCHIVED.getAttr();
                operateModuleType = OperateModuleTypeEnum.OPPORTUNITY;
                for(PaasFormDataEntityExt getName : paasFormDataEntityExtList){
                    JSONObject data = getName.getData();
                    String serialNo = getName.getSerialNo();
                    String salesOpportunityName = data.getString(SalesOpportunityEnum.NAME.getAttr());
                    salesOpportunityName = salesOpportunityName == null ? serialNo : new StringBuilder().append(serialNo).append("（").append(salesOpportunityName).append("）").toString();
                    paasName.add(salesOpportunityName);
                }
                break;
            case QUOTATION:
                if (!permSet.contains(ProPermissionAliasEnum.QUOTATION_UPDATE.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.QUOTATION_UPDATE.getMemo()));
                }
                if (isSingle && !hasDataPermission){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.QUOTATION_UPDATE.getMemo()));
                }
                attr = QuotationEnum.ARCHIVED.getAttr();
                operateModuleType = OperateModuleTypeEnum.QUOTATION;
                for(PaasFormDataEntityExt getName : paasFormDataEntityExtList){
                    JSONObject data = getName.getData();
                    String serialNo = getName.getSerialNo();
                    String quotationName = data.getString(QuotationEnum.NAME.getAttr());
                    quotationName = quotationName == null ? serialNo : new StringBuilder().append(serialNo).append("（").append(quotationName).append("）").toString();
                    paasName.add(quotationName);
                }
                break;
            case CUSTOMER_STATEMENT_STATISTIC:
                if (!permSet.contains(ProPermissionAliasEnum.ARCHIVE_STATEMENT.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CONTRACT_UPDATE.getMemo()));
                }
                if (isSingle && !hasDataPermission){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CONTRACT_UPDATE.getMemo()));
                }
                attr = CustomerStatementStatisticEnum.IS_ARCHIVED.getAttr();
                operateModuleType = OperateModuleTypeEnum.CUSTOMER_STATEMENT_STATISTIC;
                for(PaasFormDataEntityExt entityExt : paasFormDataEntityExtList){
                    if (Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode())) {
                        String status = entityExt.getData().getString(CustomerStatementStatisticDistributorEnum.STATUS.getAttr());
                        if (!Objects.equals(CustomerStatementStatusEnum.CONFIRMED.getCode(), status) && Objects.equals(archived, ArchivedEnum.ARCHIVED.getCode())) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018.getCode(), ErrorMessageConstant.UNCONFIRMED_STATEMENTS_NOT_ARCHIVED);
                        }
                    }
                    paasName.add(entityExt.getSerialNo());
                }
                break;
            case CLUE:
                if (!permSet.contains(ProPermissionAliasEnum.CLUE_ARCHIVE.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CUSTOMER_ARICHIVE.getMemo()));
                }
                if (isSingle && !hasDataPermission){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CUSTOMER_ARICHIVE.getMemo()));
                }
                attr = ClueEnum.IS_ARCHIVED.getAttr();
                operateModuleType = OperateModuleTypeEnum.CLUE;
                for(PaasFormDataEntityExt getName : paasFormDataEntityExtList){
                    JSONObject data = getName.getData();
                    paasName.add(FastJsonHelper.getStringOrDefaultFromFormData(data, ClueEnum.COMPANY_NAME.getAttr(), ""));
                }
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        proUpdateHelp.updateByIds(businessType, corpid, dataIdList, attr, archived);

        OperateTypeEnum operateTypeEnum = ArchivedEnum.getOperateByCode(archived);
        // 日志
        String nameStr = StringUtils.join(paasName, "，");
        String userName = archiveDTO.getLoginUserName();
        ArchiveOperationLogHandle archiveLogHandle = operationLogFactory.getArchiveLogHandle(SaasMarkEnum.SAAS.getCode(), businessType);
        // 未改造的还是走老的
        if(Objects.isNull(archiveLogHandle)){
            if(dataIdList.size() > 1){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ARCHIVE_FORM_DATA), userName, operateTypeEnum.getName(), nameStr);
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(operateModuleType.getName());
                infoArrPojo.setContent(nameStr);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, operateModuleType, operateTypeEnum,
                        "", "", memo, archiveDTO.getHttpHeader());
            } else if(Objects.equals(dataIdList.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ARCHIVE_FORM_DATA), userName, operateTypeEnum.getName(), nameStr);
                mongoLogHelp.buildLog(corpid, userId, userName, operateModuleType, operateTypeEnum,
                        dataIdList.get(0).toString(), nameStr, memo, archiveDTO.getHttpHeader());
            }
        }else{
            operationLogHelp.addOrDeleteArchive(archiveDTO,paasFormDataEntityExtList,nameStr,operateModuleType,archived);
        }

        // 动态日志
        addArchiveDynamic(archiveDTO, paasFormDataEntityExtList);

        // api回调（归档）
        switch (redundantTemplateTypeEnum) {
            case CUSTOMER:
                //api回调
                apiCallbackHelper.callbackBatch4Special(corpid, SaasMarkEnum.SAAS, dataIdList, operateTypeEnum, XbbRefTypeEnum.CUSTOMER);
                break;
            case CONTRACT:
            case ORDER:
                apiCallbackHelper.callbackBatch4Special(corpid, SaasMarkEnum.SAAS, dataIdList, operateTypeEnum, XbbRefTypeEnum.CONTRACT);
                break;
            case SALES_OPPORTUNITY:
                apiCallbackHelper.callbackBatch4Special(corpid, SaasMarkEnum.SAAS, dataIdList, operateTypeEnum, XbbRefTypeEnum.SALES_OPPORTUNITY);
                break;
            case CLUE:
                apiCallbackHelper.callbackBatch4Special(corpid, SaasMarkEnum.SAAS, dataIdList, operateTypeEnum, XbbRefTypeEnum.CLUE);
                break;
            default:
                break;
        }
        return new BaseVO();
    }

    private void addArchiveDynamic(ArchiveDTO archiveDTO, List<PaasFormDataEntityExt> getByIdInAndDel) {
        if (!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), archiveDTO.getDistributorMark())) {
            MainBusinessDynamicStrategy archiveDynamicStrategy = dynamicStrategyFactory.getMainBusinessDynamicStrategyByBusinessType(archiveDTO.getBusinessType());
            archiveDynamicStrategy.archive(new DynamicArchiveDTO(archiveDTO, getByIdInAndDel));
        }
    }

    @Override
    public BaseVO distribution(DistributionDTO distributionDTO) throws XbbException {
        Integer businessType = distributionDTO.getBusinessType();
        BaseVO baseVO = new BaseVO();
        TransmittableThreadLocalUtil.setValue(distributionDTO.getSaasMark(), distributionDTO.getBusinessType(), null, distributionDTO.getDistributorMark());
        if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())){
            TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), null, DistributorMarkEnum.OTHER.getCode());
            baseVO = customerDistribution(distributionDTO);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())){
            TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CLUE.getCode(), null, DistributorMarkEnum.OTHER.getCode());
            baseVO = clueDistribution(distributionDTO);
        } else {
            throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        return baseVO;
    }

    private BaseVO customerDistribution(DistributionDTO distributionDTO) throws XbbException {
        if (!distributionDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.CUSTOMER_DISTRIBUTION.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CUSTOMER_DISTRIBUTION.getMemo()));
        }
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        String opUserId = distributionDTO.getUserId();
        String corpid = distributionDTO.getCorpid();
        Integer businessType = distributionDTO.getBusinessType();
        Integer subBusinessType = distributionDTO.getSubBusinessType();
        String userId = distributionDTO.getDistributionUserId().get(0);
        List<Long> dataIdList = distributionDTO.getDataIdList();
        UserVO loginUser = distributionDTO.getLoginUser();
        Integer saasMark = distributionDTO.getSaasMark();
        Integer dataIdSize = dataIdList.size();
        List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();
            FormTeamSetEntity formTeamSet = formTeamSetHelp.getFormTeamSet(corpid, distributionDTO.getFormId(), distributionDTO.getSaasMark(), businessType, DistributorMarkEnum.OTHER.getCode());
            if(Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_SHARE.getModel())){
                teamBatchPojos = checkDataPermission4Share(dataIdList, businessType, distributionDTO.getFormId(), SaasMarkEnum.SAAS.getCode(), corpid, loginUser, UserTeamOperateTagEnum.DISTRIBUTION);
            }else if(Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_ISOLATION.getModel())){
                teamBatchPojos = checkDataPermission4Isolation(dataIdList, businessType, distributionDTO.getFormId(), corpid, loginUser, UserTeamOperateTagEnum.DISTRIBUTION);
            }


        List<Long> lackCustomerIdList = customerDataLocking(dataIdList,corpid);
        Boolean isPublic = Objects.equals(XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode(),distributionDTO.getSubBusinessType());
        //分配员工
        UserEntity userEntity = userModel.getByKey(userId,corpid);
        if (Objects.isNull(userEntity)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100065);
        }
        // 合法客户
        Set<Long> customerIdSet = new HashSet<>();
        //用于推送的目标用户、最终分配人集合
        List<Long> customerIdList = new ArrayList<>();
        // 非公海客户
        Map<Long, String> noPublicMap = new HashMap<>();
        /*List<String> notPublics = new ArrayList<>();
        List<Long> notPublicIds = new ArrayList<>();*/

        Map<String, Long> appAndMenuMap = new HashMap<>(2);
        Map<Long, String> customerNameMap = new HashMap<>();
        TeamAfterVerifyDTO teamAfterVerifyDTO = null;
        List<TeamBatchPojo> groupTeamBatchPojos = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<PaasFormDataEntityExt> publicList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!dataIdList.isEmpty()) {
            // 批量操作的数据所有都被占用，跳过所有业务逻辑
            try {
                IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
                SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
                boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIdList));
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,customerIndex.getType()));
                sourceBuilder.query(boolQueryBuilder);
                List<String> fieldList = new ArrayList<>();
                fieldList.add(ParameterConstant.APPID);
                fieldList.add(ParameterConstant.MENUID);
                fieldList.add(FieldTypeEnum.DATAID.getAlias());
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.NAME));
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.IS_PUBLIC));
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.IMPORTANT_DEGREE));
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.TYPE));
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.PUBLIC_GROUP));
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.LABEL));
                fieldList.add(ParameterConstant.FORMID);
                String[] strings = new String[fieldList.size()];
                sourceBuilder.fetchSource(fieldList.toArray(strings),null);
                SearchRequest searchRequest = new SearchRequest(customerIndex.getIndex());
                PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, dataIdList.size());
                searchRequest.source(sourceBuilder);
                XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
                if (esEntities == null) {
                    return new BaseVO();
                }

                List<PaasFormDataEntityExt> list = esEntities.getContent();
                Map<Long, PaasFormDataEntityExt> entityExtMap = new HashMap<>(list.size());
                list.forEach(item -> entityExtMap.put(item.getDataId(), item));
                // 公海池规则的校验在CustomerTeamStrategy.specialVerify()做
//                customerRuleErrorMap = canGainCustomer(corpid, dataIdList, userEntity, entityExtMap);
                for (Long customerId : dataIdList) {
                    PaasFormDataEntityExt entity = entityExtMap.get(customerId);
                    String customerName = FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), CustomerManagementEnum.NAME.getAttr(), "");
                    customerNameMap.put(customerId, customerName);
                    appAndMenuMap.put(ParameterConstant.APPID, entity.getAppId());
                    appAndMenuMap.put(ParameterConstant.MENUID, entity.getMenuId());
                    appAndMenuMap.put(ParameterConstant.FORMID, entity.getFormId());
                    if (isPublic && Objects.equals(entity.getData().getInteger(CustomerManagementEnum.IS_PUBLIC.getAttr()), 0)) {
                        noPublicMap.put(customerId, customerName);
                        /*notPublicIds.add(customerId);
                        notPublics.add(customerName);*/
                        continue;
                    }
                    // 捞取频次在CustomerTeamStrategy.afterSave()做
//                    customerRuleService.updateGainRateToRedis(corpid, userEntity);
                    customerIdList.add(customerId);
                    publicList.add(entity);

                }
               /* if (!notPublicIds.isEmpty()) {
                    //removeCustomerDataLock(notPublicIds, corpid);
                }*/
            } catch (Exception e) {
                //removeCustomerDataLock(dataIdList, corpid);
            }
            if (!customerIdList.isEmpty()) {
                Long formId = appAndMenuMap.get(ParameterConstant.FORMID);
                if (Objects.equals(XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode(),subBusinessType)) {
                    //只有公海池触发的分配才进行公海分组校验
                    String oprateTagName = UserTeamOperateTagEnum.DISTRIBUTION.getName();
                    groupTeamBatchPojos = publicGroupSeniorService.publicGroupVerify(corpid,businessType,formId,oprateTagName,distributionDTO.getLoginUser(),publicList,customerIdList);
                }
                // 数据校验
                PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
                TeamUpdateMidPOJO teamUpdateMidPOJO = new TeamUpdateMidPOJO(corpid, customerIdList, formId, SaasMarkEnum.SAAS.getCode(), distributionDTO.getBusinessType(), paasFormEntityExt.getDistributorMark(), new HashSet<>(Collections.singletonList(userId)), null, null, null, distributionDTO.getLoginUser(), isPublic,false);
                teamUpdateMidPOJO.setOprateTag(UserTeamOperateTagEnum.DISTRIBUTION.getOperateTag());
                if(isPublic){
                    teamAfterVerifyDTO = teamDataHelp.publicVerify(teamUpdateMidPOJO, false);
                }else{
                    teamAfterVerifyDTO = teamDataHelp.basicVerify(teamUpdateMidPOJO, null);
                }
                Map<String, Set<String>> addMainUserMap = teamAfterVerifyDTO.getAddMainUserMap();
                List<Long> customerIds = Optional.of(teamAfterVerifyDTO.getAddMainUserMap().keySet()).get().stream().map(Long::valueOf).collect(Collectors.toList());
                //更新一下捞取频率
                List<String> idList = addMainUserMap.entrySet().stream()
                        .filter(v -> Objects.nonNull(v.getValue()))
                        .flatMap(v -> v.getValue().stream())
                        .distinct().collect(Collectors.toList());
                List<UserEntity> users = userModel.findEntitysByUserIds(idList, corpid);
                for (Long data: customerIds) {
                    Set<String> addMainUsers = addMainUserMap.getOrDefault(String.valueOf(data), new HashSet<>());
                    List<UserEntity> collect = users.stream().filter(v -> addMainUsers.contains(v.getUserId())).collect(Collectors.toList());
                    for (UserEntity userEntitySen : collect) {
                        customerRuleService.updateGainRateToRedis(corpid,userEntitySen);
                    }
                }
                //更新数据
                if(CollectionsUtil.isNotEmpty(customerIds)){
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put(CustomerManagementEnum.DISTRIBUTION_DATE.getAttr(), DateTimeUtil.getInt());
                    if (isPublic) {
                        jsonObject.put(CustomerManagementEnum.IS_PUBLIC.getAttr(), PublicEnum.NON_PUBLIC.getCode());
                        jsonObject.put(CustomerManagementEnum.IS_ARCHIVED.getAttr(), ArchivedEnum.UN_ARCHIVED.getCode());
                    }
                    proUpdateHelp.updateByIds(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), corpid, customerIds, jsonObject);
                    // 去除客户标签
                    boolean customerSeniorModel = commonHelp.isCustomerPublicPoolSeniorModel(corpid);
                    if (customerSeniorModel){
                        transferBackRuleScriptService.deletePublicSeniorTag(corpid,customerIds,XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(),formId);
                    }else {
                        customerRuleService.deletePublicTag(corpid, customerIds);
                    }
                    //只要客户除了公海池，移除转移公海池的标签
                    tagLinkModel.deleteTagByTagTypeAndRefIdIn(corpid, TagTypeEnum.TRANSFER_CUSTOMER_RULE.getCode(), customerIds);
                }

                TeamAfterVerifyDTO finalTeamAfterVerifyDTO = teamAfterVerifyDTO;
                Runnable runnable = () -> {
                    try {

                        // 更新团队
                        if (Objects.isNull(finalTeamAfterVerifyDTO)) {
                            return;
                        }
                        teamDataHelp.batchUpdateTeam(finalTeamAfterVerifyDTO);


                        if (customerIds.isEmpty()) {
                            return;
                        }


                        List<String> customerNameList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        List<DynamicDTO> dynamicCustomerDTOList = new ArrayList<>();

                        Long appId = appAndMenuMap.getOrDefault(ParameterConstant.APPID, 0L);
                        Long menuId = appAndMenuMap.getOrDefault(ParameterConstant.MENUID, 0L);
                        // 消息推送
                        distributionMessagePush(distributionDTO, corpid, userEntity, customerIds, appId, menuId);

                        String customerPosition = I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LIST);
                        String distributeTag = I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_ALLOCATION);
                        if (isPublic) {
                            customerPosition = I18nMessageUtil.getMessage(I18nStringConstant.HIGH_SEAS);
                            distributeTag = I18nMessageUtil.getMessage(I18nStringConstant.HIGH_SEAS_DISTRIBUTION);
                        }

                        List<CustomerDynamicAddDTO> customerDynamicAddDTOList = new ArrayList<>();
                        PaasFormEntity paasForm = proFormHelp.getPaasFormIncludeDel(formId, distributionDTO.getBusinessType(), corpid);
                        for (Long customerId : customerIds) {
                            // 项目日志
                            // String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.distribution_customer), distributeTag + distributionDTO.getLoginUserName(), customerPosition, userEntity.getName());
                            String customerName = customerNameMap.get(customerId);
                            customerNameList.add(customerName);
                            customerIdSet.add(customerId);
                            if (Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), distributionDTO.getDistributorMark())) {
                                // 项目日志
                                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.distribution_customer), distributeTag + distributionDTO.getLoginUserName(), customerPosition, userEntity.getName());
                                CustomerDynamicAddDTO customerDynamicAddDTO = new CustomerDynamicAddDTO();
                                customerDynamicAddDTO.setCorpid(corpid);
                                customerDynamicAddDTO.setUserId(userId);
                                customerDynamicAddDTO.setMemo(memo);
                                customerDynamicAddDTO.setCustomerId(customerId);
                                customerDynamicAddDTO.setCustomerName(customerName);
                                customerDynamicAddDTO.setLogType(ProjectLogEnum.CUSTOMER_DISTRIBUTE.getSubType());
                                customerDynamicAddDTO.setDataId(0L);
                                customerDynamicAddDTO.setCommunicateBusinessText("");
                                customerDynamicAddDTO.setDistributorMark(distributionDTO.getDistributorMark());
                                customerDynamicAddDTOList.add(customerDynamicAddDTO);
                            }
                        }

                        if (Objects.isNull(distributionDTO.getFormId())) {
                            distributionDTO.setFormId(formId);
                        }

                        // 项目日志插入
                        if (Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), distributionDTO.getDistributorMark())) {
                            customerCommunicateService.batchAddCustomerDynamic(customerDynamicAddDTOList, corpid);
                        } else {
                            CustomerDynamicStrategy customerDynamicStrategy = dynamicStrategyFactory.getCustomerDynamicStrategy(ProjectLogEnum.CUSTOMER_DISTRIBUTE.getSubType());
                            customerDynamicStrategy.distribute(new DynamicDistributeDTO(distributionDTO, customerIds, customerNameMap, userEntity));
                        }

                        //分配客户日志
                        String userName = distributionDTO.getLoginUserName();
                        String logMemo = StringUtils.join(customerNameList, "、");
                        if (customerNameList.size() >= 1) {
                            //用户“%s”给%s批量分配了负责人“%s”，合计%s条数据操作成功
                            String memo = "";
                            if(isPublic){
                                memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DISTRIBUTION_CUSTOMER_IN_PUBLIC),
                                        userName, paasForm.getName(), userEntity.getName(), customerNameList.size());
                            }else{
                                memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DISTRIBUTION_CUSTOMER),
                                        userName, paasForm.getName(), userEntity.getName(), customerNameList.size());
                            }
                            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                            InfoArrPojo infoArrPojo = new InfoArrPojo();
                            infoArrPojo.setTitle(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_OPERATION_OBJECT));
                            infoArrPojo.setContent(logMemo);
                            infoArrPojoList.add(infoArrPojo);
                            mongoLogHelp.buildLog4InfoArrWithoutAsync(infoArrPojoList, corpid, opUserId, userName, OperateModuleTypeEnum.CUSTOMER, OperateTypeEnum.DISTRIBUTE,
                                    "", "", memo, distributionDTO.getHttpHeader());
                        }
                    } catch (XbbException e) {
                        LOG.error("distribution error:", e);
                    }
                };
                threadPoolBeanConfig.batchAddOrDelTeam().execute(runnable);
            }
        }
        List<TeamBatchPojo> teamBatchPojo4Verify = Objects.nonNull(teamAfterVerifyDTO) ? teamAfterVerifyDTO.getTeamBatchPojos() : new ArrayList<>();
        teamBatchPojos.addAll(teamBatchPojo4Verify);
        teamBatchPojos.addAll(groupTeamBatchPojos);
        //重新封装一下异常信息
        packageDistributionError(distributionDTO.getBusinessType(), distributionDTO.getSaasMark(),teamBatchPojos, noPublicMap, lackCustomerIdList, corpid, teamBatchVO, dataIdSize, UserTeamOperateTagEnum.DISTRIBUTION.getName());
        /*if (!notPublics.isEmpty()) {
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.NOT_PUBLIC));
            commonHelp.mergeFailMsg(notPublics, dataIdSize, teamBatchPojo, OperateTypeEnum.DISTRIBUTE.getName(), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }

        if (!lackCustomerIdList.isEmpty()) {
            TeamBatchPojo teamBatchPojo = lackError(lackCustomerIdList, dataIdSize, corpid, teamBatchVO, OperateTypeEnum.DISTRIBUTE.getName());
            teamBatchPojos.add(teamBatchPojo);
        }

        if (!teamBatchPojos.isEmpty()) {
            if(MapUtils.isEmpty(teamAfterVerifyDTO.getAddMainUserMap())){
                //所有都捞取失败
                teamBatchVO.setResultMsg(ListBatchResultEnum.OPERATE_FAIL.getMsg());
                teamBatchVO.setResultType(ListBatchResultEnum.OPERATE_FAIL.getAlias());
            }
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
        }*/
        return teamBatchVO;
    }

    private BaseVO clueDistribution(DistributionDTO distributionDTO) throws XbbException {
        if (!distributionDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.CLUE_DISTRIBUTION.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CLUE_DISTRIBUTION.getMemo()));
        }
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        String corpid = distributionDTO.getCorpid();
        Integer businessType = distributionDTO.getBusinessType();
        Integer subBusinessType = distributionDTO.getSubBusinessType();
        String userId = distributionDTO.getDistributionUserId().get(0);
        Integer saasMark = distributionDTO.getSaasMark();
        List<Long> dataIdList = distributionDTO.getDataIdList();
        Integer dataIdSize = dataIdList.size();
        UserVO loginUser = distributionDTO.getLoginUser();
        List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();
        //校验数据权限(团队权限&共享权限)
            FormTeamSetEntity formTeamSet = formTeamSetHelp.getFormTeamSet(corpid, distributionDTO.getFormId(), distributionDTO.getSaasMark(), businessType, DistributorMarkEnum.OTHER.getCode());
            if(Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_SHARE.getModel())){
                teamBatchPojos = checkDataPermission4Share(dataIdList, businessType, distributionDTO.getFormId(), SaasMarkEnum.SAAS.getCode(), corpid, loginUser, UserTeamOperateTagEnum.DISTRIBUTION);
            }else if(Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_ISOLATION.getModel())){
                teamBatchPojos = checkDataPermission4Isolation(dataIdList, businessType, distributionDTO.getFormId(), corpid, loginUser, UserTeamOperateTagEnum.DISTRIBUTION);
            }
        List<Long> lackClueIdList = clueDataLocking(dataIdList,corpid);
        Set<Long> lockClues = new HashSet<>();
        if (Objects.equals(distributionDTO.getSubBusinessType(), XbbRefTypeEnum.CLUE_PUBLIC.getCode())) {
            lockClues = clueAutoAssignmentLocking(dataIdList,corpid);
        }
        Boolean isPublic = Objects.equals(XbbRefTypeEnum.CLUE_PUBLIC.getCode(),distributionDTO.getSubBusinessType());
        //分配员工
        UserEntity userEntity = userModel.getByKey(userId,corpid);
        if (Objects.isNull(userEntity)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100065);
        }
        // 合法线索
        Set<Long> clueIdSet = new HashSet<>();
        //用于推送的目标用户、最终分配人集合
        List<Long> clueIdList = new ArrayList<>();
        // 非公海线索
        Map<Long, String> noPublicMap = new HashMap<>();
        /*List<String> notPublics = new ArrayList<>();
        List<Long> notPublicIds = new ArrayList<>();*/

        Map<String, Long> appAndMenuMap = new HashMap<>(2);
        Map<Long, String> clueNameMap = new HashMap<>();
        TeamAfterVerifyDTO teamAfterVerifyDTO = null;
        List<TeamBatchPojo> groupTeamBatchPojos = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<PaasFormDataEntityExt> publicList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!dataIdList.isEmpty()) {
            // 批量操作的数据所有都被占用，跳过所有业务逻辑
            try {
                SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
                boolQueryBuilder.filter(termQuery("del",0 ));
                boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIdList));
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CLUE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                List<String> fieldList = new ArrayList<>();
                fieldList.add(ParameterConstant.APPID);
                fieldList.add(ParameterConstant.MENUID);
                fieldList.add(FieldTypeEnum.DATAID.getAlias());
                fieldList.add(FieldTypeEnum.FORM_ID.getAlias());
                fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.COMPANY_NAME));
                fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.IS_PUBLIC));
                fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.CLUE_STATUS));
                fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.CLUE_SOURCE));
                fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.PUBLIC_GROUP));
                fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.LABEL));
                String[] strings = new String[fieldList.size()];
                sourceBuilder.fetchSource(fieldList.toArray(strings),null);

                SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CLUE.getIndex());
                PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, dataIdList.size());
                searchRequest.source(sourceBuilder);
                XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
                if (esEntities == null) {
                    return new BaseVO();
                }

                List<PaasFormDataEntityExt> list = esEntities.getContent();
                Map<Long, PaasFormDataEntityExt> entityExtMap = new HashMap<>(list.size());
                list.forEach(item -> entityExtMap.put(item.getDataId(), item));

                // 公海池规则的判断处理ClueTeamStrategy.specialVerify
//                clueRuleErrorMap = canGainClue(corpid, dataIdList, userEntity, entityExtMap);
                for (Long clueId : dataIdList) {
                    PaasFormDataEntityExt entity = entityExtMap.get(clueId);
                    String clueName = FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), ClueEnum.COMPANY_NAME.getAttr(), "");
                    clueNameMap.put(clueId, clueName);
                    appAndMenuMap.put(ParameterConstant.APPID, entity.getAppId());
                    appAndMenuMap.put(ParameterConstant.MENUID, entity.getMenuId());
                    appAndMenuMap.put(ParameterConstant.FORMID, entity.getFormId());
                    if (isPublic && Objects.equals(entity.getData().getInteger(ClueEnum.IS_PUBLIC.getAttr()), 0)) {
                        noPublicMap.put(clueId, clueName);
                        /*notPublicIds.add(clueId);
                        notPublics.add(clueName);*/
                        continue;
                    }
                    // 捞取频次在ClueTeamStrategy.afterSave()做
//                    clueRuleService.updateGainRateToRedis(corpid, userEntity);
                    clueIdList.add(clueId);
                    publicList.add(entity);
                }
                /*if (!notPublicIds.isEmpty()) {
                }*/
            } catch (Exception e) {
            }
            if (!clueIdList.isEmpty()) {
                Long formId = appAndMenuMap.get(ParameterConstant.FORMID);
                if (Objects.equals(XbbRefTypeEnum.CLUE_PUBLIC.getCode(),subBusinessType)) {
                    //只有线索公海池分配才进行分组管理员权限校验
                    String oprateTagName = UserTeamOperateTagEnum.DISTRIBUTION.getName();
                    groupTeamBatchPojos = publicGroupSeniorService.publicGroupVerify(corpid,businessType,formId,oprateTagName,distributionDTO.getLoginUser(),publicList,clueIdList);

                }
                PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
                //线索分配，下游客户团队不用继承,setIsInheritance设为true
                TeamUpdateMidPOJO teamUpdateMidPOJO = new TeamUpdateMidPOJO(corpid, clueIdList, formId, SaasMarkEnum.SAAS.getCode(), paasFormEntityExt.getBusinessType(), paasFormEntityExt.getDistributorMark(), new HashSet<>(Collections.singletonList(userId)), null, null, null, distributionDTO.getLoginUser(), isPublic,false);
                teamUpdateMidPOJO.setOprateTag(UserTeamOperateTagEnum.DISTRIBUTION.getOperateTag());
                if(isPublic){
                    teamAfterVerifyDTO = teamDataHelp.publicVerify(teamUpdateMidPOJO, false);
                }else{
                    teamAfterVerifyDTO = teamDataHelp.basicVerify(teamUpdateMidPOJO, null);

                }

                //更新数据
                Map<String, Set<String>> addMainUserMap = teamAfterVerifyDTO.getAddMainUserMap();
                List<Long> clueIds = Optional.of(addMainUserMap.keySet()).get().stream().map(Long::valueOf).collect(Collectors.toList());
                //更新一下捞取频率
                List<String> idList = addMainUserMap.entrySet().stream()
                        .filter(v -> Objects.nonNull(v.getValue()))
                        .flatMap(v -> v.getValue().stream())
                        .distinct().collect(Collectors.toList());
                List<UserEntity> users = userModel.findEntitysByUserIds(idList, corpid);
                for (Long data: clueIds) {
                    Set<String> addMainUsers = addMainUserMap.getOrDefault(String.valueOf(data), new HashSet<>());
                    List<UserEntity> collect = users.stream().filter(v -> addMainUsers.contains(v.getUserId())).collect(Collectors.toList());
                    for (UserEntity userEntitySen : collect) {
                        clueRuleService.updateGainRateToRedis(corpid,userEntitySen);
                    }
                }
                //更新数据和动态更新公海池标签
                if(CollectionsUtil.isNotEmpty(clueIds)){
                    Map<String, Object> updateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    updateMap.put(ClueEnum.DISTRIBUTION_DATE.getAttr(), DateTimeUtil.getInt());
                    if (isPublic) {
                        updateMap.put(ClueEnum.IS_PUBLIC.getAttr(), PublicEnum.NON_PUBLIC.getCode());
                        updateMap.put(ClueEnum.IS_ARCHIVED.getAttr(), ArchivedEnum.UN_ARCHIVED.getCode());
                    }
                    JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(updateMap));
                    proUpdateHelp.updateByIds(XbbRefTypeEnum.CLUE.getCode(), corpid, clueIds, jsonObject);
                    // 去除公海池标志
                    boolean cluePublicSeniorModel = commonHelp.isCluePublicPoolSeniorModel(corpid);
                    if (cluePublicSeniorModel){
                        transferBackRuleScriptService.deletePublicSeniorTag(corpid,clueIds,XbbRefTypeEnum.CLUE.getCode(),formId);
                    }else {
                        clueRuleService.deletePublicTag(corpid, clueIds);
                    }
                    //只要线索出了公海池，移除转移公海池的标签
                    tagLinkModel.deleteTagByTagTypeAndRefIdIn(corpid, TagTypeEnum.TRANSFER_CLUE_RULE.getCode(), clueIds);
                }
                TeamAfterVerifyDTO finalTeamAfterVerifyDTO = teamAfterVerifyDTO;
                Runnable runnable = () -> {
                    try {
                        // 更新团队
                        if (Objects.isNull(finalTeamAfterVerifyDTO)) {
                            return;
                        }
                        teamDataHelp.batchUpdateTeam(finalTeamAfterVerifyDTO);

                        if (clueIds.isEmpty()) {
                            return;
                        }
                        //api回调-线索分配
                        apiCallbackHelper.callbackBatch4Special(corpid, SaasMarkEnum.SAAS, clueIds, OperateTypeEnum.EDIT, XbbRefTypeEnum.CLUE);

                        Long appId = appAndMenuMap.getOrDefault(ParameterConstant.APPID, 0L);
                        Long menuId = appAndMenuMap.getOrDefault(ParameterConstant.MENUID, 0L);
                        // 消息推送
                        distributClueMessagePush(distributionDTO, corpid, userEntity, clueIds, appId, menuId);

                        String cluePosition = I18nMessageUtil.getMessage(I18nStringConstant.CLUE_LIST);
                        if (isPublic) {
                            cluePosition = I18nMessageUtil.getMessage(I18nStringConstant.HIGH_SEAS);
                        }


                        //分配线索日志
                        List<String> clueNameList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

                        for (Long clueId : clueIds) {
                            String orDefault = clueNameMap.getOrDefault(clueId, "");
                            clueNameList.add(orDefault);
                        }

                        String userName = distributionDTO.getLoginUserName();
                        String logMemo = StringUtils.join(clueNameList, "，");
                        if (clueNameList.size() > 1) {
                            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DISTRIBUTION_CLUE), userName, cluePosition, userEntity.getName(), clueNameList.size());
                            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                            InfoArrPojo infoArrPojo = new InfoArrPojo();
                            infoArrPojo.setTitle(ClueEnum.COMPANY_NAME.getAttrName());
                            infoArrPojo.setContent(logMemo);
                            infoArrPojoList.add(infoArrPojo);
                            mongoLogHelp.buildLog4InfoArrWithoutAsync(infoArrPojoList, corpid, distributionDTO.getUserId(), userName, OperateModuleTypeEnum.CLUE, OperateTypeEnum.DISTRIBUTE,
                                    "", "", memo, distributionDTO.getHttpHeader());
                        } else if (Objects.equals(clueNameList.size(), 1)) {
                            String idStr = null;
                            for (Long id : clueIdSet) {
                                if (Objects.isNull(idStr)) {
                                    idStr = id.toString();
                                }
                            }
                            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DISTRIBUTION_CLUE), userName, cluePosition, logMemo, userEntity.getName());
                            mongoLogHelp.buildLogWithoutAsync(corpid, distributionDTO.getUserId(), userName, OperateModuleTypeEnum.CLUE, OperateTypeEnum.DISTRIBUTE,
                                    idStr, logMemo, memo, distributionDTO.getHttpHeader());
                        }
                    } catch (XbbException e) {
                        LOG.error("distribution clue error:", e);
                    }
                };
                threadPoolBeanConfig.batchAddOrDelTeam().execute(runnable);
            }
        }

        List<TeamBatchPojo> teamBatchPojo4Verify = Objects.nonNull(teamAfterVerifyDTO) ? teamAfterVerifyDTO.getTeamBatchPojos() : new ArrayList<>();
        teamBatchPojos.addAll(teamBatchPojo4Verify);
        teamBatchPojos.addAll(groupTeamBatchPojos);
        //重新封装一下异常信息
        packageDistributionError(distributionDTO.getBusinessType(), distributionDTO.getSaasMark(),teamBatchPojos, noPublicMap, lackClueIdList, corpid, teamBatchVO, dataIdSize, UserTeamOperateTagEnum.DISTRIBUTION.getName());
        /*if (!notPublics.isEmpty()) {
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.NOT_PUBLIC));
            commonHelp.mergeFailMsg(notPublics, dataIdSize, teamBatchPojo, OperateTypeEnum.DISTRIBUTE.getName(), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }

        if (!lackClueIdList.isEmpty()) {
            TeamBatchPojo teamBatchPojo = lackClueError(lackClueIdList, dataIdSize, corpid, teamBatchVO, OperateTypeEnum.DISTRIBUTE.getName());
            teamBatchPojos.add(teamBatchPojo);
        }
        if (!lockClues.isEmpty()) {
            TeamBatchPojo teamBatchPojo = lockClueError(lockClues, dataIdSize, corpid, teamBatchVO, OperateTypeEnum.DISTRIBUTE.getName());
            teamBatchPojos.add(teamBatchPojo);
        }

        if (!teamBatchPojos.isEmpty()) {
            if(MapUtils.isEmpty(teamAfterVerifyDTO.getAddMainUserMap())){
                //所有都捞取失败
                teamBatchVO.setResultMsg(ListBatchResultEnum.OPERATE_FAIL.getMsg());
                teamBatchVO.setResultType(ListBatchResultEnum.OPERATE_FAIL.getAlias());
            }
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
        }*/
        return teamBatchVO;
    }

    /**
     * 客户/线索分配接口整合成最后返回的异常信息
     * 客户/线索捞取接口
     *
     * @param businessType
     * @param saasMark
     * @param teamBatchPojos
     * @param noPublicMap
     * @param lackCustomerIdList
     * @param corpid
     * @param teamBatchVO
     * @param dataIdSize
     * @param operateName
     */
    private void packageDistributionError(Integer businessType, Integer saasMark, List<TeamBatchPojo> teamBatchPojos, Map<Long, String> noPublicMap,
                                          List<Long> lackCustomerIdList, String corpid, TeamBatchVO teamBatchVO, Integer dataIdSize, String operateName) throws XbbException {
        List<Long> hasExistErrorDataIdList = new ArrayList();
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            hasExistErrorDataIdList = teamBatchPojos.stream().map(TeamBatchPojo::getDataId).collect(Collectors.toList());
        }
        if (MapUtils.isNotEmpty(noPublicMap)) {
            for (Map.Entry<Long, String> noPublicEntry : noPublicMap.entrySet()) {
                if (hasExistErrorDataIdList.contains(noPublicEntry.getKey())) {
                    continue;
                }
                TeamBatchPojo teamBatchPojo = new TeamBatchPojo(UserTeamErrorCodeEnum.API_ERROR_271022.getCode(), UserTeamErrorCodeEnum.API_ERROR_271022.getMsg(),
                        noPublicEntry.getValue(), operateName);
                teamBatchPojos.add(teamBatchPojo);
            }
        }
            if (CollectionsUtil.isNotEmpty(lackCustomerIdList)) {
            Map<Long, String> nameOrSeriNoMap = new HashMap<>();
            userTeamHelp.getEntityMap(businessType, lackCustomerIdList, corpid, nameOrSeriNoMap, saasMark);
            List<String> lackName = new ArrayList<>(lackCustomerIdList.size());
            for (Long id : lackCustomerIdList) {
                lackName.add(nameOrSeriNoMap.getOrDefault(id, ""));
            }
            commonHelp.batchSameErrorPackage(lackName, operateName,
                    UserTeamErrorCodeEnum.API_ERROR_271020.getCode(), UserTeamErrorCodeEnum.API_ERROR_271020.getMsg(), teamBatchPojos);
        }
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            commonHelp.batchFailMsg(teamBatchPojos, dataIdSize, teamBatchVO);
        }

    }

    /**
     * Description: 分配消息 推送
     * @param distributionDTO
     * @param corpid
     * @param userEntity
     * @param customerIdList
     * @param appId
     * @param menuId
     * @return void
     * @author 魏荣杰
     * @date 2019/6/13 19:12
     * @since v1.0
     */
    private void distributionMessagePush(DistributionDTO distributionDTO, String corpid, UserEntity userEntity, List<Long> customerIdList, Long appId, Long menuId) throws XbbException {
        // 客户分配消息推送
        List<String> pushUserList = new ArrayList<>();

        CustomerPushSet customerPushSet = new CustomerPushSet();
        PushSetEntity pushSetEntity = customerPushSet.getPushSet(corpid, PushTypeEnum.CUSTOMER_DISTRIBUTION_PUSH.getSubCode(), pushSetModel);

        if (Objects.equals(pushSetEntity.getEnable(), 1)) {
            String pushObjectStr = pushSetEntity.getPushObject();
            JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectStr);
            String typeStr = pushObject.getString("type");
            JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeStr);
            for (Object object : typeJsonArray) {
                JSONObject jsonObject = (JSONObject) object;
                Integer enable = jsonObject.getInteger("enable");
                if (Objects.equals(enable, 1)) {
                    String alias = jsonObject.getString("alias");
                    if (Objects.equals(alias, PushObjectTypeEnum.MAINUSER.getAlias())) {
                        pushUserList.addAll(customerUserModel.getCustomerUserIdList(corpid, customerIdList, 1));
                    } else if (Objects.equals(alias, PushObjectTypeEnum.COLLABORATOR.getAlias())) {
                        pushUserList.addAll(customerUserModel.getCustomerUserIdList(corpid, customerIdList, 0));
                    }
                }
            }

            UserVO loginUser = distributionDTO.getLoginUser();
            UserEntity logUserEntity = new UserEntity();
            BeanUtil.copyProperties(loginUser, logUserEntity);
            pushUserList = pushHelper.getPushUserIdList(logUserEntity, pushObjectStr, pushUserList, DateUtil.getInt());
            pushUserList.remove(loginUser.getUserId());
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(appId, menuId, null, null, customerIdList, SaasMarkEnum.SAAS.getCode(), distributionDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER.getCode());
            MessageRabbitMqDTO messageRabbitMqDTO2Other = new MessageRabbitMqDTO(corpid, pushUserList, customerIdList, 0, null, I18nMessageUtil.getMessage(CustomerPushConstant.CUSTOMER_DISTRIBUTION_TITLE), String.format(I18nMessageUtil.getMessage(CustomerPushConstant.CUSTOMER_DISTRIBUTION_CONTENT_OTHER), loginUser.getName(), customerIdList.size(), userEntity.getName()), null, options);
            //发送给其他人
            baseProducer.sendMessage(PushTypeEnum.CUSTOMER_DISTRIBUTION_PUSH, messageRabbitMqDTO2Other);


            pushUserList = new ArrayList<>(distributionDTO.getDistributionUserId());
            pushUserList.remove(loginUser.getUserId());
            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, customerIdList, 0, null, I18nMessageUtil.getMessage(CustomerPushConstant.CUSTOMER_DISTRIBUTION_TITLE), String.format(I18nMessageUtil.getMessage(CustomerPushConstant.CUSTOMER_DISTRIBUTION_CONTENT), loginUser.getName(), customerIdList.size()), null, options);
            //发送给分配人
            baseProducer.sendMessage(PushTypeEnum.CUSTOMER_DISTRIBUTION_PUSH, messageRabbitMqDTO);
        }
    }

    /**
     * Description: 线索分配消息 推送
     * @param distributionDTO
     * @param corpid
     * @param userEntity
     * @param clueIdList
     * @param appId
     * @param menuId
     * @return void
     */
    private void distributClueMessagePush(DistributionDTO distributionDTO, String corpid, UserEntity userEntity, List<Long> clueIdList, Long appId, Long menuId) throws XbbException {
        // 客户分配消息推送
        List<String> pushUserList = new ArrayList<>();

        CluePushSet cluePushSet = new CluePushSet();
        PushSetEntity pushSetEntity = cluePushSet.getPushSet(corpid, PushTypeEnum.CLUE_DISTRIBUTION_PUSH.getSubCode(), pushSetModel);

        if (Objects.equals(pushSetEntity.getEnable(), 1)) {
            String pushObjectStr = pushSetEntity.getPushObject();
            JSONObject pushObject = JsonHelperUtil.parseObject(pushObjectStr);
            String typeStr = pushObject.getString("type");
            JSONArray typeJsonArray = JsonHelperUtil.parseArray(typeStr);
            for (Object object : typeJsonArray) {
                JSONObject jsonObject = (JSONObject) object;
                Integer enable = jsonObject.getInteger("enable");
                if (Objects.equals(enable, 1)) {
                    String alias = jsonObject.getString("alias");
                    if (Objects.equals(alias, PushObjectTypeEnum.MAINUSER.getAlias())) {
                        pushUserList.addAll(clueUserModel.getClueUserIds(corpid, clueIdList, 1));
                    } else if (Objects.equals(alias, PushObjectTypeEnum.COLLABORATOR.getAlias())) {
                        pushUserList.addAll(clueUserModel.getClueUserIds(corpid, clueIdList, 0));
                    }
                }
            }

            UserVO loginUser = distributionDTO.getLoginUser();
            UserEntity logUserEntity = new UserEntity();
            BeanUtil.copyProperties(loginUser, logUserEntity);
            pushUserList = pushHelper.getPushUserIdList(logUserEntity, pushObjectStr, pushUserList, DateUtil.getInt());
            pushUserList.remove(loginUser.getUserId());
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(appId, menuId, null, null, clueIdList, SaasMarkEnum.SAAS.getCode(), distributionDTO.getBusinessType(), XbbRefTypeEnum.ALL_CLUE.getCode());
            MessageRabbitMqDTO messageRabbitMqDTO2Other = new MessageRabbitMqDTO(corpid, pushUserList, clueIdList, 0, null, I18nMessageUtil.getMessage(CluePushConstant.CLUE_DISTRIBUTION_TITLE), String.format(I18nMessageUtil.getMessage(CluePushConstant.CLUE_DISTRIBUTION_CONTENT_OTHER), loginUser.getName(), clueIdList.size(), userEntity.getName()), null, options);
            //发送给其他人
            baseProducer.sendMessage(PushTypeEnum.CLUE_DISTRIBUTION_PUSH, messageRabbitMqDTO2Other);


            pushUserList = new ArrayList<>(distributionDTO.getDistributionUserId());
            pushUserList.remove(loginUser.getUserId());
            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, clueIdList, 0, null, I18nMessageUtil.getMessage(CluePushConstant.CLUE_DISTRIBUTION_TITLE), String.format(I18nMessageUtil.getMessage(CluePushConstant.CLUE_DISTRIBUTION_CONTENT), loginUser.getName(), clueIdList.size()), null, options);
            //发送给分配人
            baseProducer.sendMessage(PushTypeEnum.CLUE_DISTRIBUTION_PUSH, messageRabbitMqDTO);
        }
    }

    @Override
    public BaseVO backCustomer(ListBatchDTO listBatchDTO) throws XbbException {
        Integer businessType = listBatchDTO.getBusinessType();
        TransmittableThreadLocalUtil.setValue(listBatchDTO.getSaasMark(), listBatchDTO.getBusinessType(), null, listBatchDTO.getDistributorMark());
        BaseVO baseVO;
        if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
            baseVO = backCustomerToPublic(listBatchDTO);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
            baseVO = backClueToPublic(listBatchDTO);
        } else {
            throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        return baseVO;
    }

    private BaseVO backCustomerToPublic(ListBatchDTO listBatchDTO) throws XbbException {
        UserVO loginUser = listBatchDTO.getLoginUser();
        String corpid = listBatchDTO.getCorpid();
        List<Long> dataIdList = listBatchDTO.getDataIdList();
        Integer businessType = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        Integer saasMark = listBatchDTO.getSaasMark();
        //校验表单权限
        if (!loginUser.getPermSet().contains(ProPermissionAliasEnum.CUSTOMER_BACK.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CUSTOMER_BACK.getMemo()));
        }
        Integer dataIdSize = dataIdList.size();
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();
        //校验数据权限(团队权限&共享权限)
        if (Objects.equals(listBatchDTO.getIsBatch(), BasicConstant.ZERO)){
            PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormDataWithTeam(corpid, saasMark, businessType, dataIdList.get(0));
            if (Objects.isNull(paasFormDataEntityExt)){
                return new BaseVO();
            }
            VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
            boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
            if (!hasDataPermission){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CUSTOMER_BACK.getMemo()));
            }
        }else{
            FormTeamSetEntity formTeamSet = formTeamSetHelp.getFormTeamSet(corpid, listBatchDTO.getFormId(), listBatchDTO.getSaasMark(), businessType, DistributorMarkEnum.OTHER.getCode());
            if(Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_SHARE.getModel())){
                teamBatchPojos = checkDataPermission4Share(dataIdList, businessType, listBatchDTO.getFormId(), saasMark, corpid, loginUser, UserTeamOperateTagEnum.BACK_TO_PUBLIC);
            }else if(Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_ISOLATION.getModel())){
                teamBatchPojos = checkDataPermission4Isolation(dataIdList, businessType, listBatchDTO.getFormId(), corpid, loginUser, UserTeamOperateTagEnum.BACK_TO_PUBLIC);
            }
        }
        IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, businessType, SaasMarkEnum.SAAS.getCode());
        List<String> multiOwner = new ArrayList<>();
        String userId = listBatchDTO.getUserId();
        Long formId = listBatchDTO.getFormId();
        Integer distributorMark = listBatchDTO.getDistributorMark();
        UserEntity userEntity = userModel.getByKey(userId,listBatchDTO.getCorpid());
        boolean isBoss = userEntity.isOriAdmin();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIdList));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, customerIndex.getType()));
        sourceBuilder.query(boolQueryBuilder);
        List<String> fieldList = new ArrayList<>();
        fieldList.add(FieldTypeEnum.DATAID.getAlias());
        fieldList.add(FieldTypeEnum.FORM_ID.getAlias());
        fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.NAME));
        fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.BACK_NUM));
        String[] strings = new String[fieldList.size()];
        sourceBuilder.fetchSource(fieldList.toArray(strings),null);
        SearchRequest searchRequest = new SearchRequest(customerIndex.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, dataIdList.size());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            return new BaseVO();
        }
        //这个接口前端没传formId，主动获取
        List<PaasFormDataEntityExt> content = esEntities.getContent();
        Map<Long, String> customerNameMap = new HashMap<>(dataIdList.size());
        List<UpdateDataEntity> updateDataEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        for (PaasFormDataEntityExt entityExt : esEntities.getContent()) {
            String name = FastJsonHelper.getStringOrDefaultFromFormData(entityExt.getData(), CustomerManagementEnum.NAME.getAttr(), "");
            customerNameMap.put(entityExt.getDataId(), name);
            //退回次数
            Integer backNum = FastJsonHelper.getIntegerOrDefaultFromFormData(entityExt.getData(), CustomerManagementEnum.BACK_NUM.getAttr(), 0);
            //退回次数集合
            JSONObject temp = new JSONObject();
            temp.put(CustomerManagementEnum.BACK_NUM.getAttr(), backNum + 1);
            temp.put(CustomerManagementEnum.IS_PUBLIC.getAttr(), 1);
            temp.put(CustomerManagementEnum.BACK_PUBLIC_DATE.getAttr(), DateTimeUtil.getInt());
            UpdateDataEntity updateData = ExplainUtil.getUpdateData(entityExt.getDataId(), temp, corpid);
            updateDataEntityList.add(updateData);
        }
        if (CollectionsUtil.isNotEmpty(content) && Objects.isNull(formId)) {
            formId = content.get(0).getFormId();
        }
        if(Objects.isNull(distributorMark)){
            distributorMark = DistributorMarkEnum.OTHER.getCode();
        }
        List<Long> lackCustomerList = customerDataLocking(dataIdList,corpid);
        if (!dataIdList.isEmpty()) {
            String loginUserName = listBatchDTO.getLoginUserName();
            List<String> customerNameList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (Long customerId : dataIdList) {
                customerNameList.add(customerNameMap.get(customerId));
            }
            //updateCustomerTeam 方法有对customerIdList有操作,这边备份一下
            List<Long> copyList = new ArrayList<>(dataIdList);
            //批量操作的数据所有都被占用，跳过所有业务逻辑
            if (isBoss) {
                //更新客户
                Long finalFormId = formId;
                Integer finalDistributorMark = distributorMark;
                //批量更新退回次数
                if (CollectionsUtil.isNotEmpty(updateDataEntityList)) {
                    proUpdateHelp.updateBatch(1, businessType, corpid, updateDataEntityList);
                }
                Runnable runnable = () -> {
                    //设置退回时间、负责人设为前负责人
                    try {
                        //解散团队
                        teamDataHelp.disbandedTeam(corpid, finalFormId,listBatchDTO.getSaasMark(),listBatchDTO.getBusinessType(), finalDistributorMark,dataIdList,null,WriteRequest.RefreshPolicy.NONE);
                        //removeCustomerDataLock(customerIdList, corpid);
                    } catch (XbbException e) {
                        //removeCustomerDataLock(customerIdList, corpid);
                        LOG.error("批量解散客户团队失败", e);
                    }
                    //解除关注
                    customerFocusModel.unFocusBatch(copyList, corpid);

                    if (Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), listBatchDTO.getDistributorMark())) {
                        // 记录项目日志
                        List<CustomerDynamicAddDTO> customerDynamicAddDTOList = new ArrayList<>();
                        String communicateMemo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.RETURN_CUSTOMER_PUBLIC), loginUserName);
                        for (Long customerId : dataIdList) {
                            CustomerDynamicAddDTO customerDynamicAddDTO = new CustomerDynamicAddDTO();
                            customerDynamicAddDTO.setCorpid(corpid);
                            customerDynamicAddDTO.setUserId(userId);
                            customerDynamicAddDTO.setMemo(communicateMemo);
                            customerDynamicAddDTO.setCustomerId(customerId);
                            customerDynamicAddDTO.setCustomerName(customerNameMap.getOrDefault(customerId, ""));
                            customerDynamicAddDTO.setDataId(0L);
                            customerDynamicAddDTO.setCommunicateBusinessType(null);
                            customerDynamicAddDTO.setCommunicateBusinessText("");
                            customerDynamicAddDTO.setLogType(ProjectLogEnum.CUSTOMER_BACK.getSubType());
                            customerDynamicAddDTO.setDistributorMark(listBatchDTO.getDistributorMark());
                            customerDynamicAddDTOList.add(customerDynamicAddDTO);
                        }
                        try {
                            customerCommunicateService.batchAddCustomerDynamic(customerDynamicAddDTOList, corpid);
                        } catch (XbbException e) {
                            e.printStackTrace();
                            LOG.error("listBatchService.backCustomerToPublic中customerCommunicateService.batchAddCustomerDynamic报错：", e);
                        }
                    }

                };
                threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
            } else {
                //这段逻辑封装成了 userTeamService.updateCustomerTeam
                try {

                    userTeamService.updateCustomerTeam(userEntity, dataIdList, UpdateCustomerTeamScenesEnum.USER,formId,listBatchDTO.getSaasMark(),listBatchDTO.getBusinessType(),listBatchDTO.getDistributorMark(),null);

                    //removeCustomerDataLock(copyList, corpid);
                } catch (Exception e) {
                    LOG.error("客户退回公海池更新团队失败",e);
                    //removeCustomerDataLock(customerIdList, corpid);
                }
            }
            //评分计算(批量 客户退回公海池) 捞取，退回公海池，移交，负责团队变跟，这些只修改分配时间的不需要触发评分
            //scoreCalculateService.asyncUpdateBatchDataScore(XbbRefTypeEnum.CUSTOMER_MANAGEMENT,corpid,customerIdList);

            // api回调(退回公海池)
            //api回调方法会操作原始集合，影响了异步的操作，故直接copy一个丢进去
            List<Long> customerIdList4Api = new ArrayList<>(copyList);
            apiCallbackHelper.callbackBatch4Special(corpid, SaasMarkEnum.SAAS, customerIdList4Api, OperateTypeEnum.EDIT, XbbRefTypeEnum.CUSTOMER);
            Runnable runnable = () -> {
                try {
                    //客户退回公海池后，该客户绑定的未推送的提醒同步删除
                    try{
                        deleteRemindByDataIn(businessType,dataIdList,corpid);
                    }catch (Exception e){
                        LOG.error("客户退回公海池，同步删除提醒失败");
                    }
                    //访客计划同步删除
                } catch (Exception e) {
                    LOG.error("backCustomer error:", e);
                }
            };

            //退回公海池日志
            BackToPublicDTO backToPublicDTO = new BackToPublicDTO(listBatchDTO,esEntities.getContent(),customerNameList,listBatchDTO.getIsBatch());
            customerOperationLogHandle.backToPublic(backToPublicDTO);

            // 记录客户动态日志
            if (Objects.isNull(listBatchDTO.getFormId())) {
                listBatchDTO.setFormId(formId);
            }

            if (!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), listBatchDTO.getDistributorMark())) {
                CustomerDynamicStrategy customerDynamicStrategy = dynamicStrategyFactory.getCustomerDynamicStrategy(ProjectLogEnum.CUSTOMER_BACK.getSubType());
                customerDynamicStrategy.back(DynamicBackDTO.initDynamicBackDTO(listBatchDTO, copyList, customerNameMap));
            }

            threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
            // 去除客户标签
            boolean customerSeniorModel = commonHelp.isCustomerPublicPoolSeniorModel(corpid);
            if (customerSeniorModel){
                transferBackRuleScriptService.deletePublicSeniorTag(corpid,dataIdList, businessType,formId);
            }else {
                customerRuleService.deletePublicTag(corpid, dataIdList);
            }
            //只要客户除了公海池，移除转移公海池的标签
            if(CollectionsUtil.isNotEmpty(copyList)){
                tagLinkModel.deleteTagByTagTypeAndRefIdIn(corpid, TagTypeEnum.TRANSFER_CUSTOMER_RULE.getCode(), copyList);
            }
        }
        if (!lackCustomerList.isEmpty()){
            for (Long customerId : lackCustomerList) {
                multiOwner.add(customerNameMap.getOrDefault(customerId, ""));
            }
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.USED_BY_OTHER));
            commonHelp.mergeFailMsg(multiOwner, dataIdSize, teamBatchPojo, OperateTypeEnum.RETURN_TO_PUBLIC.getName(), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
            //String name = customerService.getCutomerNameStr(lackCustomerList,corpid);
            //String msg = "已有他人操作，客户" + name + "退回公海池失败";
            //throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,msg);
        }
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            if (Objects.equals(BasicConstant.ONE, listBatchDTO.getIsBatch())) {
                teamBatchVO.setTeamBatchPojos(teamBatchPojos);
                commonHelp.batchFailMsg(teamBatchPojos, dataIdSize, teamBatchVO);
            }else {
                throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_271004.getCode(), teamBatchPojos.get(BasicConstant.ZERO).getFailMsgReason());
            }
        }
        return teamBatchVO;
    }

    private BaseVO backClueToPublic(ListBatchDTO listBatchDTO) throws XbbException {
        String corpid = listBatchDTO.getCorpid();
        UserVO loginUser = listBatchDTO.getLoginUser();
        Integer businessType = XbbRefTypeEnum.CLUE.getCode();
        Integer saasMark = listBatchDTO.getSaasMark();
        //校验表单权限
        if (!loginUser.getPermSet().contains(ProPermissionAliasEnum.CLUE_BACK.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CLUE_BACK.getMemo()));
        }
        List<Long> clueIdList = listBatchDTO.getDataIdList();
        Integer dataIdSize = clueIdList.size();
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();
        //校验数据权限(团队权限&共享权限)
        if (Objects.equals(listBatchDTO.getIsBatch(), BasicConstant.ZERO)){
            PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormDataWithTeam(corpid, saasMark, businessType, listBatchDTO.getDataIdList().get(0));
            if (Objects.isNull(paasFormDataEntityExt)){
                return new BaseVO();
            }
            VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
            boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
            if (!hasDataPermission){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CLUE_BACK.getMemo()));
            }
        }else{
            FormTeamSetEntity formTeamSet = formTeamSetHelp.getFormTeamSet(corpid, listBatchDTO.getFormId(), listBatchDTO.getSaasMark(), businessType, DistributorMarkEnum.OTHER.getCode());
            if(Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_SHARE.getModel())){
                teamBatchPojos = checkDataPermission4Share(listBatchDTO.getDataIdList(), businessType, listBatchDTO.getFormId(), saasMark, corpid, loginUser, UserTeamOperateTagEnum.BACK_TO_PUBLIC);
            }else if(Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_ISOLATION.getModel())){
                teamBatchPojos = checkDataPermission4Isolation(listBatchDTO.getDataIdList(), businessType, listBatchDTO.getFormId(), corpid, loginUser, UserTeamOperateTagEnum.BACK_TO_PUBLIC);
            }
        }
        List<String> multiOwner = new ArrayList<>();
        String userId = listBatchDTO.getUserId();
        Long formId = listBatchDTO.getFormId();
        Integer distributorMark = listBatchDTO.getDistributorMark();
        UserEntity userEntity = userModel.getByKey(userId,listBatchDTO.getCorpid());
        boolean isBoss = userEntity.isOriAdmin();

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), clueIdList));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CLUE.getType()));
        sourceBuilder.query(boolQueryBuilder);
        List<String> fieldList = new ArrayList<>();
        fieldList.add(FieldTypeEnum.DATAID.getAlias());
        fieldList.add(FieldTypeEnum.FORM_ID.getAlias());
        fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.COMPANY_NAME));
        fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.BACK_NUM));
        String[] strings = new String[fieldList.size()];
        sourceBuilder.fetchSource(fieldList.toArray(strings),null);

        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CLUE.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, clueIdList.size());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            return new BaseVO();
        }
        List<PaasFormDataEntityExt> content = esEntities.getContent();
        Map<Long, String> clueNameMap = new HashMap<>(clueIdList.size());
        List<UpdateDataEntity> updateDataEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt entityExt : content) {
            String name = FastJsonHelper.getStringOrDefaultFromFormData(entityExt.getData(), ClueEnum.COMPANY_NAME.getAttr(), "");
            clueNameMap.put(entityExt.getDataId(), name);
            //退回次数
            Integer backNum = FastJsonHelper.getIntegerOrDefaultFromFormData(entityExt.getData(), ClueEnum.BACK_NUM.getAttr(), 0);
            //退回次数集合
            JSONObject temp = new JSONObject();
            temp.put(ClueEnum.BACK_NUM.getAttr(), backNum + 1);
            temp.put(ClueEnum.IS_PUBLIC.getAttr(), 1);
            temp.put(ClueEnum.BACK_PUBLIC_DATE.getAttr(), DateTimeUtil.getInt());
            UpdateDataEntity updateData = ExplainUtil.getUpdateData(entityExt.getDataId(), temp, corpid);
            updateDataEntityList.add(updateData);
        }
        if (CollectionsUtil.isNotEmpty(content) && Objects.isNull(formId)) {
            formId = content.get(0).getFormId();
        }
        if(Objects.isNull(distributorMark)){
            distributorMark = DistributorMarkEnum.OTHER.getCode();
        }
        List<Long> lackClueList = clueDataLocking(clueIdList,corpid);
        if (!clueIdList.isEmpty()) {
            String loginUserName = listBatchDTO.getLoginUserName();
            List<String> customerNameList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (Long clueId : clueIdList) {
                customerNameList.add(clueNameMap.get(clueId));
            }
            //updateCustomerTeam 方法有对customerIdList有操作,这边备份一下
            List<Long> copyList = new ArrayList<>(clueIdList);
            //批量操作的数据所有都被占用，跳过所有业务逻辑
            if (isBoss) {
                //更新线索
                Long finalFormId = formId;
                Integer finalDistributorMark = distributorMark;
                //批量更新退回次数
                if (CollectionsUtil.isNotEmpty(updateDataEntityList)) {
                    proUpdateHelp.updateBatch(1, businessType, corpid, updateDataEntityList);
                }
                Runnable runnable = () -> {
                    //设置退回时间、负责人设为前负责人
                    try {
                        clueUserModel.disbandedTeam(corpid, clueIdList, null);
                        //teamDataHelp.disbandedTeam(corpid, finalFormId,listBatchDTO.getSaasMark(),listBatchDTO.getBusinessType(), finalDistributorMark,clueIdList,null);
                    } catch (XbbException e) {
                        LOG.error("批量解散线索团队失败", e);
                    }
                };
                //评分计算(退回公海池) 捞取，退回公海池，移交，负责团队变跟，这些只修改分配时间的不需要触发评分
//                scoreCalculateService.asyncUpdateBatchDataScore(XbbRefTypeEnum.CLUE,corpid,clueIdList);
                threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
            } else {
                try {
                    userTeamService.updateClueTeam(userEntity, clueIdList, UpdateCustomerTeamScenesEnum.USER,formId,listBatchDTO.getSaasMark(),listBatchDTO.getBusinessType(),distributorMark, null);
                } catch (Exception e) {
                }
            }
            //api回调-线索退回公海池
            //api回调方法会操作原始集合，影响了异步的操作，故直接copy一个丢进去
            List<Long> clueIdList4Api = new ArrayList<>(copyList);
            apiCallbackHelper.callbackBatch4Special(corpid, SaasMarkEnum.SAAS, clueIdList4Api, OperateTypeEnum.EDIT, XbbRefTypeEnum.CLUE);
            Runnable runnable = () -> {
                try {
                    //线索退回公海池后，该线索绑定的未推送的提醒同步删除
                    try{
                        deleteRemindByDataIn(businessType,clueIdList,corpid);
                    }catch (Exception e){
                        LOG.error("线索退回公海池，同步删除提醒失败");
                    }
                    //退回公海池日志
                    String logMemo = StringUtils.join(customerNameList, "，");
                    if (copyList.size() > 1) {
                        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_BACK_CLUE), loginUserName, XbbRefTypeEnum.CLUE.getName(), copyList.size());
                        List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        InfoArrPojo infoArrPojo = new InfoArrPojo();
                        infoArrPojo.setTitle(ClueEnum.COMPANY_NAME.getAttrName());
                        infoArrPojo.setContent(logMemo);
                        infoArrPojoList.add(infoArrPojo);
                        try {
                            mongoLogHelp.buildLog4InfoArrWithoutAsync(infoArrPojoList, corpid, userId, loginUserName, OperateModuleTypeEnum.CLUE, OperateTypeEnum.RETURN_TO_PUBLIC,
                                    "", "", memo, listBatchDTO.getHttpHeader());
                        } catch (XbbException e) {
                            e.printStackTrace();
                        }
                    } else if (Objects.equals(copyList.size(), 1)) {
                        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BACK_CLUE), loginUserName, XbbRefTypeEnum.CLUE.getName(), logMemo);
                        try {
                            mongoLogHelp.buildLogWithoutAsync(corpid, userId, loginUserName, OperateModuleTypeEnum.CLUE, OperateTypeEnum.RETURN_TO_PUBLIC,
                                    copyList.get(0).toString(), logMemo, memo, listBatchDTO.getHttpHeader());
                        } catch (XbbException e) {
                            e.printStackTrace();
                        }
                    }
                } catch (Exception e) {
                    LOG.error("backClue error:", e);
                }
            };
            threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
            // 删除线索公海池标签
            boolean cluePublicSeniorModel = commonHelp.isCluePublicPoolSeniorModel(corpid);
            if (cluePublicSeniorModel){
                transferBackRuleScriptService.deletePublicSeniorTag(corpid,copyList, businessType,formId);
            }else {
                clueRuleService.deletePublicTag(corpid, copyList);
            }
            //只要客户除了公海池，移除转移公海池的标签
            if(CollectionsUtil.isNotEmpty(copyList)){
                tagLinkModel.deleteTagByTagTypeAndRefIdIn(corpid, TagTypeEnum.TRANSFER_CLUE_RULE.getCode(), copyList);
            }
        }
        if (!lackClueList.isEmpty()){
            for (Long clueId : lackClueList) {
                multiOwner.add(clueNameMap.getOrDefault(clueId, ""));
            }
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.USED_BY_OTHER));
            commonHelp.mergeFailMsg(multiOwner, dataIdSize, teamBatchPojo, OperateTypeEnum.RETURN_TO_PUBLIC.getName(), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            if (Objects.equals(BasicConstant.ONE, listBatchDTO.getIsBatch())) {
                teamBatchVO.setTeamBatchPojos(teamBatchPojos);
                commonHelp.batchFailMsg(teamBatchPojos, dataIdSize, teamBatchVO);
            }else {
                throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_271004.getCode(), teamBatchPojos.get(BasicConstant.ZERO).getFailMsgReason());
            }
        }
        return teamBatchVO;
    }

    /**
     * 根据业务类型和 dataIn 删除该业务数据绑定的提醒
     * @param businessType
     * @param dataIn
     * @param corpid
     */
    private void deleteRemindByDataIn(Integer businessType, List<Long> dataIn,String corpid) {

        if(Objects.nonNull(businessType) && CollectionsUtil.isNotEmpty(dataIn) && Objects.nonNull(corpid)){
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
            Map<String, Object> param = new HashMap<>(16);
            param.put("corpid", corpid);
            param.put("isPush", 0);//是否已经推送
            param.put("del", 0);
            param.put("status", 0);//钉钉状态
            param.put("isRemind", 1);//是否是提醒
            switch(xbbRefTypeEnum){
                case CUSTOMER_MANAGEMENT:
                case CLUE:
                    param.put("refEntity", businessType);
                    break;
                default:
                    //不属于上面的业务类型-1，让查询不到提醒
                    param.put("refEntity", -1);
            }
            param.put("refIdIn", dataIn);
            //查询客户关联的未推送的提醒
            List<PushEntity> pushEntities = pushModel.findEntitys(param);
            if(CollectionsUtil.isNotEmpty(pushEntities)){
                List<Long> pushIdList = pushEntities.stream().map(PushEntity::getId).collect(Collectors.toList());
                //组装参数，删除提醒
                DelRemindDTO delRemindDTO = new DelRemindDTO();
                delRemindDTO.setCorpid(corpid);
                for(Long pushId : pushIdList){
                    delRemindDTO.setDataId(pushId);
                    try{
                        deleteRemind(delRemindDTO);
                    }catch (Exception e){
                        //删除发生异常，继续执行循环的下一个
                        LOG.error("客户或线索退回公海池或被删除时，同步删除提醒失败,pushId-{}-",pushId);
                        continue;
                    }
                }
            }
        }

    }


    private TeamBatchVO distributorHandover(ChangeMainDTO changeMainDTO) throws XbbException{
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();
        String corpid = changeMainDTO.getCorpid();
        String userId = changeMainDTO.getUserId();
        String loginUserName = changeMainDTO.getLoginUserName();
        List<Long> dataIdList = changeMainDTO.getDataIdList();
        Integer dataIdSize = dataIdList.size();
        // 移交人
        String removeUserId = changeMainDTO.getOriginUserId();
        List<Long> lackCustomerList = customerDataLocking(dataIdList,corpid);
        Map<Long, String> removeUserNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<String> multiOwner = new ArrayList<>();
        List<String> self = new ArrayList<>();

        List<Long> successList = new ArrayList<>();
        // 客户id与userNames的映射
        Map<Long, String> customerUserNamesMap = new HashMap<>();
        String handoverUserId = changeMainDTO.getChangeUserId();
        UserEntity userEntity = userModel.getByKey(handoverUserId, corpid);
        if (Objects.isNull(userEntity)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100065);
        }
        String userName = userEntity.getName();
        Map<Integer, List<String>> customerRuleErrorMap = new HashMap<>(BasicConstant.ONE);
        if (!dataIdList.isEmpty()) {
            Map<Long, PaasFormDataEntityExt> entityExtMap = new HashMap<>(dataIdList.size());
            Map<Long, String> customerNameMap = saasCustomerHelp.getCustomerNameMap(dataIdList, corpid, entityExtMap);
            // 公海池规则的判断处理
            customerRuleErrorMap = canGainCustomer(corpid, dataIdList, userEntity, entityExtMap);

            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put("corpid", corpid);
            map.put("customerIdIn", dataIdList);
            //        map.put("isMain",1);
            map.put("del", 0);
            if (Objects.nonNull(removeUserId)) {
                map.put("userIdIn",Arrays.asList(removeUserId, handoverUserId));
            }
            List<CustomerUserEntity> customerUserEntityList = customerUserModel.findEntitys(map);

            if (Objects.nonNull(removeUserId)) {
                boolean handoverUserExist = false;
                for (CustomerUserEntity userTeamEntity : customerUserEntityList) {
                    if (Objects.equals(userTeamEntity.getUserId(), handoverUserId) && Objects.equals(userTeamEntity.getIsMain(), BasicConstant.MAIN_USER)) {
                        // app详情页团队移交时，如果移交用户已存在，且为负责人那么报错处理
                        handoverUserExist = true;
                        break;
                    }
                }
                if (handoverUserExist) {
                    //removeCustomerDataLock(dataIdList, corpid);
                    TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
                    teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.HANDOVER_USER_EXIST));
                    commonHelp.mergeFailMsg(dataIdList, dataIdList.size(), teamBatchPojo, OperateTypeEnum.HANDOVER.getName(), teamBatchVO);
                    teamBatchPojos.add(teamBatchPojo);
                    teamBatchVO.setTeamBatchPojos(teamBatchPojos);
                    return teamBatchVO;
                }
            }
            //合法客户
            Set<Long> handoverIdSet = new HashSet<>();
            //不合法的客户
            Set<Long> removeHandoverIdSet = new HashSet<>();
            //可以被移交的客户以及被干掉的负责人key:客户id;value:客户协同人表id
            Map<Long, Long> removeUserMap = new HashMap<>();

            //需要删除的关系表id（协同人）
            List<Long> collaboratorIds = new ArrayList<>();

            for (CustomerUserEntity entity : customerUserEntityList) {
                Long customerId = entity.getDataId();

                //当移交目标是客户当协同人是，需要删除协同人关系
                if (Objects.equals(entity.getIsMain(), 0)) {
                    if (Objects.equals(entity.getUserId(), handoverUserId)) {
                        collaboratorIds.add(entity.getId());
                    }
                    continue;
                }

                if (handoverIdSet.contains(customerId)) {
                    //多负责人
                    if (!removeHandoverIdSet.contains(customerId)) {
                        multiOwner.add(customerNameMap.getOrDefault(customerId, ""));
                        removeHandoverIdSet.add(customerId);
                    }
                } else if (Objects.equals(entity.getUserId(), handoverUserId)) {
                    //负责人是自己
                    if (!removeHandoverIdSet.contains(customerId)) {
                        self.add(customerNameMap.getOrDefault(customerId, ""));
                        removeHandoverIdSet.add(customerId);
                    }
                } else {
                    removeUserMap.put(customerId, entity.getId());
                    handoverIdSet.add(customerId);
                    removeUserNameMap.put(customerId, entity.getUserId());
                    String userNames = customerUserNamesMap.get(customerId);
                    if (StringUtil.isEmpty(userNames)) {
                        // 因为多负责人不允许移交，所以这里只有一个负责人
                        customerUserNamesMap.put(customerId, entity.getUserName());
                    }
                }
            }
            //排除没有负责人的客户
            //removeCustomerDataLock(new ArrayList<>(removeHandoverIdSet), corpid);
            handoverIdSet.removeAll(removeHandoverIdSet);
            List<Long> removeIdList = new ArrayList<>();
            String userAvatar = userEntity.getAvatar();
            List<CustomerUserEntity> insertBatchList = new ArrayList<>();
            Iterator<Long> iterator = handoverIdSet.iterator();
            try {
                while (iterator.hasNext()) {
                    Long customerId = iterator.next();
                    customerRuleService.updateGainRateToRedis(corpid, userEntity);
                    removeIdList.add(removeUserMap.get(customerId));
                    CustomerUserEntity customerUserEntity = new CustomerUserEntity();
                    customerUserEntity.setCorpid(corpid);
                    customerUserEntity.setDataId(customerId);
                    customerUserEntity.setIsMain(1);
                    customerUserEntity.setUserId(handoverUserId);
                    customerUserEntity.setUserName(userName);
                    customerUserEntity.setUserAvatar(userAvatar);
                    insertBatchList.add(customerUserEntity);
                    successList.add(customerId);
                }
            } catch (Exception e) {
                LOG.error("批量移交未抛出的异常 === ", e);
                //removeCustomerDataLock(new ArrayList<>(handoverIdSet), corpid);
            }
            if (!removeIdList.isEmpty() && !insertBatchList.isEmpty()) {
                try {
                    removeIdList.addAll(collaboratorIds);
                    userTeamService.handoverRemoveUser(corpid, removeIdList);
                    userTeamService.handoverInsertUser(corpid, insertBatchList, userId);
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put(ManagementBaseEnum.DISTRIBUTION_DATE.getAttr(), DateTimeUtil.getInt());
                    proUpdateHelp.updateByIds(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), corpid, successList, jsonObject);
                    //removeCustomerDataLock(new ArrayList<>(handoverIdSet), corpid);
                } catch (Exception e) {
                    LOG.error("handover error,corpid:", corpid + ",userId:" + userId + ",removeIdList:" + JSONArray.toJSONString(removeIdList) + ",successList:" + JSONArray.toJSONString(successList));
                    //removeCustomerDataLock(new ArrayList<>(handoverIdSet), corpid);
                }
            }
        }
        // 最大公海池规则和捞取频率规则如果有报错，就所以的都不会处理，这边就直接返回，前负责人是针对某些数据报错，所以单独加在后面
        customerRuleError(dataIdSize, customerRuleErrorMap, teamBatchPojos, teamBatchVO, OperateTypeEnum.HANDOVER.getName());
        if (!teamBatchPojos.isEmpty()) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
            return teamBatchVO;
        }

        if (!customerRuleErrorMap.isEmpty()) {
            List<String> errorName = customerRuleErrorMap.get(CustomerRuleEnum.PRE_PRINCIPAL_RULE.getCode());
            if (CollectionsUtil.isNotEmpty(errorName)) {
                TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
                teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.THE_FORMER_PERSON_IN_CHARGE_CANNOT_TAKE_IT));
                commonHelp.mergeFailMsg(errorName, dataIdSize, teamBatchPojo, OperateTypeEnum.HANDOVER.getName(), teamBatchVO);
                teamBatchPojos.add(teamBatchPojo);
            }
        }

        if (!multiOwner.isEmpty()){
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.FULL_FAIL_REASON_FULL_OWNER));
            commonHelp.mergeFailMsg(multiOwner, dataIdSize, teamBatchPojo, OperateTypeEnum.HANDOVER.getName(), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }
        if (!self.isEmpty()){
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.SELF_FAIL_REASON_FULL_OWNER));
            commonHelp.mergeFailMsg(self, dataIdSize, teamBatchPojo, OperateTypeEnum.HANDOVER.getName(), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }
        if (!lackCustomerList.isEmpty()) {
            TeamBatchPojo teamBatchPojo = lackError(lackCustomerList, dataIdSize, corpid, teamBatchVO, OperateTypeEnum.HANDOVER.getName());
            teamBatchPojos.add(teamBatchPojo);
        }

        if (!successList.isEmpty()){
            Runnable runnable = () -> {
                try {
                    // 客户移交消息推送
                    List<String> preUserNamesList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    List<String> customerNameList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    List<Long> customerIdList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for (Long handOverId : successList) {
                        PaasFormDataEntityExt paasFormDataEntityExt = customerModel.getByKey(handOverId, corpid);
                        if (Objects.isNull(paasFormDataEntityExt)) {
                            continue;
                        }

                        JSONObject data = paasFormDataEntityExt.getData();
                        String distributorName = data.getString(DistributorEnum.NAME.getAttr());

                        List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.DISTRIBUTOR_HANDOVER_PUSH.getCode(), PushTypeEnum.DISTRIBUTOR_HANDOVER_PUSH.getSubCode(), changeMainDTO.getLoginUser(), paasFormDataEntityExt);
                        PushRefTypePojo.Options options = new PushRefTypePojo.Options(paasFormDataEntityExt.getAppId(), paasFormDataEntityExt.getMenuId(), paasFormDataEntityExt.getFormId(), handOverId, Collections.singletonList(handOverId), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), XbbRefTypeEnum.CUSTOMER.getCode());
                        // 推送被移交用户
                        UserEntity handOverUser = userModel.getByKey(changeMainDTO.getChangeUserId(), corpid);

                        MessageRabbitMqDTO messageRabbitMqToOtherDTO = new MessageRabbitMqDTO(corpid, Collections.singletonList(removeUserNameMap.getOrDefault(handOverId,"")), Collections.singletonList(handOverId), 0, null, I18nMessageUtil.getMessage(DistributorPushConstant.DISTRIBUTOR_HANDOVER_TO_OTHER_TITLE), String.format(I18nMessageUtil.getMessage(DistributorPushConstant.DISTRIBUTOR_HANDOVER_TO_OTHER_CONTENT), distributorName, handOverUser.getName()), null, options);

                        // 推送移交用户
                        MessageRabbitMqDTO messageRabbitMqToYouDTO = new MessageRabbitMqDTO(corpid, Collections.singletonList(handOverUser.getUserId()), Collections.singletonList(handOverId), 0, null, I18nMessageUtil.getMessage(DistributorPushConstant.DISTRIBUTOR_HANDOVER_TO_YOU_TITLE), String.format(I18nMessageUtil.getMessage(DistributorPushConstant.DISTRIBUTOR_HANDOVER_TO_YOU_CONTENT), changeMainDTO.getLoginUserName(), distributorName), null, options);

                        // 推送消息设置的人员
                        MessageRabbitMqDTO messageRabbitMqToPushSetDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(handOverId), 0, null, I18nMessageUtil.getMessage(DistributorPushConstant.DISTRIBUTOR_HANDOVER_TITLE), String.format(I18nMessageUtil.getMessage(DistributorPushConstant.DISTRIBUTOR_HANDOVER_CONTENT), distributorName, handOverUser.getName()), null, options);

                        baseProducer.sendMessage(PushTypeEnum.DISTRIBUTOR_HANDOVER_PUSH, messageRabbitMqToOtherDTO);
                        baseProducer.sendMessage(PushTypeEnum.DISTRIBUTOR_HANDOVER_PUSH, messageRabbitMqToYouDTO);
                        baseProducer.sendMessage(PushTypeEnum.DISTRIBUTOR_HANDOVER_PUSH, messageRabbitMqToPushSetDTO);

                        // 客户移交项目日志
                        String preUserNames = customerUserNamesMap.get(handOverId) == null ? "" : customerUserNamesMap.get(handOverId);
                        preUserNamesList.add(preUserNames);
                        String communicateMemo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.DISTRIBUTOR_TRANSFER), loginUserName, preUserNames, distributorName, userName);
                        distributorCommunicateService.addCustomerDynamic(corpid, changeMainDTO.getUserId(), communicateMemo, handOverId, distributorName, ProjectLogEnum.DISTRIBUTOR_HANDOVER.getSubType());

                        // 客户电话做为同名客户识别的标识
                        String cusPhone = data.getString(DistributorEnum.PHONE.getAttr());
                        if (cusPhone != null) {
                            JSONArray phoneArray = JsonHelperUtil.parseArray(cusPhone);
                            if (!phoneArray.isEmpty()) {
                                JSONObject phoneObj = phoneArray.getJSONObject(0);
                                if (phoneObj != null) {
                                    String phone = phoneObj.get("text_2") == null ? "" : phoneObj.get("text_2").toString();
                                    StringBuilder sb = new StringBuilder();
                                    distributorName = sb.append(distributorName).append("（").append(phone).append("）").toString();
                                }
                            }
                        }
                        customerNameList.add(distributorName);
                        customerIdList.add(handOverId);
                    }

                    // 操作记录日志，移交
                    // 原负责人 去重
                    HashSet preUserDuplicate = new HashSet(preUserNamesList);
                    preUserNamesList.clear();
                    preUserNamesList.addAll(preUserDuplicate);
                    String preUserNamesStr = StringUtils.join(preUserNamesList, "，");
                    // 原负责人负责的所有客户
                    String customerNameStr = StringUtils.join(customerNameList, "，");
                    if(successList.size() > 1){
                        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_HANDOVER_DISTRIBUTOR), loginUserName, preUserNamesStr, userName, successList.size());
                        List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        InfoArrPojo infoArrPojo = new InfoArrPojo();
                        infoArrPojo.setTitle(CustomerManagementEnum.NAME.getAttrName());
                        infoArrPojo.setContent(customerNameStr);
                        infoArrPojoList.add(infoArrPojo);
                        mongoLogHelp.buildLog4InfoArrWithoutAsync(infoArrPojoList, corpid, userId, loginUserName, OperateModuleTypeEnum.DISTRIBUTOR, OperateTypeEnum.HANDOVER,
                                "", "", memo, changeMainDTO.getHttpHeader());
                    } else if(Objects.equals(successList.size(), 1)){
                        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_HANDOVER_DISTRIBUTOR), loginUserName, preUserNamesStr, customerNameStr, userName);
                        mongoLogHelp.buildLogWithoutAsync(corpid, userId, loginUserName, OperateModuleTypeEnum.DISTRIBUTOR, OperateTypeEnum.HANDOVER,
                                customerIdList.get(0).toString(), customerNameStr, memo, changeMainDTO.getHttpHeader());
                    }
                } catch (XbbException e) {
                    LOG.error("listBatchService.distributorHandover中distributorCommunicateService.batchAddCustomerDynamic报错：", e);
                } catch (Exception e) {
                    LOG.error("listBatchService.distributorHandover中distributorCommunicateService.batchAddCustomerDynamic报错：", e);
                }
            };
            threadPoolBeanConfig.batchAddOrDelTeam().execute(runnable);

            customerRuleService.deletePublicTag(changeMainDTO.getCorpid(), new ArrayList<>(successList));

        }
        if (teamBatchPojos.size() > 0) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
        }
        return teamBatchVO;
    }


    private TeamBatchVO otherHandover(ChangeMainDTO changeMainDTO) throws XbbException{
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        String userId = changeMainDTO.getUserId();
        String loginUserName = changeMainDTO.getLoginUserName();
        List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();
        UserVO loginUser = changeMainDTO.getLoginUser();
        String corpid = changeMainDTO.getCorpid();
        Integer businessType = changeMainDTO.getBusinessType();
        String handoverUserId = changeMainDTO.getChangeUserId();
        Integer saasMark = changeMainDTO.getSaasMark();
        List<Long> dataIdList = changeMainDTO.getDataIdList();
        List<Long> originalIds = new ArrayList<>(dataIdList);
        //没有权限的直接挡掉
        if (Objects.equals(changeMainDTO.getIsBatch(), BasicConstant.ZERO)){
            PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormDataWithTeam(corpid, saasMark, businessType, dataIdList.get(0));
            if (Objects.isNull(paasFormDataEntityExt)){
                return new TeamBatchVO();
            }
            VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
            boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
            if (!hasDataPermission){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), OperateTypeEnum.HANDOVER.getName()));
            }
        }else{
            teamBatchPojos = checkDataPermission4Share(dataIdList, businessType, changeMainDTO.getFormId(), saasMark, corpid, loginUser, UserTeamOperateTagEnum.HANDOVER);
        }
        Integer dataIdSize = dataIdList.size();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIdList));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, businessType, saasMark);
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,indexTypeEnum.getType()));
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, dataIdList.size());
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest,searchRequest,PaasFormDataEntityExt.class);
        if (Objects.isNull(esEntities) || CollectionsUtil.isEmpty(esEntities.getContent())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
        }
        List<PaasFormDataEntityExt> content = esEntities.getContent();

        String redisPrefix = teamDataHelp.getRedisPrefix(saasMark, businessType);
        List<Long> lackIdList = dataLocking(dataIdList,corpid, redisPrefix);

        UserEntity userEntity = userModel.getByKey(handoverUserId, corpid);
        if (Objects.isNull(userEntity)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100065);
        }
        String userName = userEntity.getName();

        List<String> self = new ArrayList<>();
        List<String> noPermissions = new ArrayList<>();
        List<Long> handoverIds = new ArrayList<>();
        List<String> serialNos = new ArrayList<>();
        Set<String> handoverUserIds = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : content) {
            if (Objects.equals(entityExt.getOwnerId(), handoverUserId)) {
                self.add(entityExt.getSerialNo());
            } else {
                serialNos.add(entityExt.getSerialNo());
                handoverIds.add(entityExt.getId());
                String owner = entityExt.getOwnerId();
                if (StringUtil.isNotEmpty(owner)) {
                    handoverUserIds.add(owner);
                }
            }
        }
        originalIds.removeAll(handoverIds);
        Set<String> preUserNamesList = new HashSet<>(handoverUserIds.size());
        List<UserEntity> byUserId = userModel.getByUserId(new ArrayList<>(handoverUserIds), corpid);
        for (UserEntity entity : byUserId) {
            preUserNamesList.add(entity.getName());
        }
        if (!handoverIds.isEmpty()) {
            changeMainDTO.setDataIdList(handoverIds);
            //removeDataLock(handoverIds, corpid, redisPrefix);
            userTeamService.handoverUpdateOwner(changeMainDTO);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(ManagementBaseEnum.DISTRIBUTION_DATE.getAttr(), DateTimeUtil.getInt());
            proUpdateHelp.updateByIds(businessType, corpid, handoverIds, jsonObject);
        }

        if (!self.isEmpty()){
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.SELF_FAIL_REASON_FULL_OWNER));
            commonHelp.mergeFailMsg(self, dataIdSize, teamBatchPojo, OperateTypeEnum.HANDOVER.getName(), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }

        if (!noPermissions.isEmpty()){
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.NO_PERMISSION_FOR_HANDOVER));
            commonHelp.mergeFailMsg(noPermissions, dataIdSize, teamBatchPojo, OperateTypeEnum.HANDOVER.getName(), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }

        if (!lackIdList.isEmpty()){
            List<String> lackName = new ArrayList<>(lackIdList.size());
            for (PaasFormDataEntityExt entityExt : content) {
                if (lackIdList.contains(entityExt.getId())) {
                    lackName.add(entityExt.getSerialNo());
                }
            }
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.USED_BY_OTHER));
            commonHelp.mergeFailMsg(lackName, dataIdSize, teamBatchPojo, OperateTypeEnum.HANDOVER.getName(), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }

        if (!handoverIds.isEmpty()){
            Runnable runnable = () -> {
                // 移交消息推送
                try {
                    // 操作记录日志，移交
                    // 原负责人 去重
                    String preUserNamesStr = StringUtils.join(preUserNamesList, "，");
                    // 原负责人负责的所有
                    String nameOrSeriaNoStr = StringUtils.join(serialNos, "，");
                    OperateModuleTypeEnum operateModuleTypeEnum = getOperateType(businessType);
                    String businessName = RedundantTemplateTypeEnum.getByCode(businessType).getName();
                    if (handoverIds.size() > 1) {
                        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_HANDOVER), loginUserName, preUserNamesStr, businessName, userName, handoverIds.size());
                        List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        InfoArrPojo infoArrPojo = new InfoArrPojo();
                        infoArrPojo.setTitle(businessName);
                        infoArrPojo.setContent(nameOrSeriaNoStr);
                        infoArrPojoList.add(infoArrPojo);
                        mongoLogHelp.buildLog4InfoArrWithoutAsync(infoArrPojoList, corpid, userId, loginUserName, operateModuleTypeEnum, OperateTypeEnum.HANDOVER,
                                "", "", memo, changeMainDTO.getHttpHeader());
                    } else if (Objects.equals(handoverIds.size(), 1)) {
                        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_HANDOVER), loginUserName, preUserNamesStr, businessName, nameOrSeriaNoStr, userName);
                        mongoLogHelp.buildLogWithoutAsync(corpid, userId, loginUserName, operateModuleTypeEnum, OperateTypeEnum.HANDOVER,
                                handoverIds.get(0).toString(), nameOrSeriaNoStr, memo, changeMainDTO.getHttpHeader());
                    }
                } catch (XbbException e) {
                    LOG.error("ListBatchService.otherTeamHandover error",e);
                } catch (Exception e) {
                    LOG.error("ListBatchService.otherTeamHandover error",e);
                }
            };
            threadPoolBeanConfig.batchAddOrDelTeam().execute(runnable);
        }
        if (teamBatchPojos.size() > 0) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
        }
        return teamBatchVO;

    }



    private List<UserEntity> getCustomerUserList(Long customerId, String corpid) {
        List<UserEntity> list = new ArrayList<>();
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("customerId", customerId);
        param.put("corpid", corpid);
        param.put("isMain", 1);
        param.put("del", 0);
        List<CustomerUserEntity> customerUserList = customerUserModel.findEntitys(param);

        List<String> userIdIn = new ArrayList<>();
        for(CustomerUserEntity customerUser : customerUserList){
            userIdIn.add(customerUser.getUserId());
        }
        userIdIn.add("-1");
        param.clear();
        param.put("userIdIn", userIdIn);
        param.put("corpid", corpid);
        param.put("del", 0);
        List<UserEntity> userList = userModel.findEntitys(param);

        Map<String, UserEntity> userMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for(UserEntity user : userList){
            userMap.put(user.getUserId(), user);
        }

        for(CustomerUserEntity customerUser : customerUserList){
            if(userMap.containsKey(customerUser.getUserId())){
                UserEntity userEntity = (UserEntity) CloneUtil.deepClone(userMap.get(customerUser.getUserId()));
                userEntity.setIsMain(customerUser.getIsMain());
                list.add(userEntity);
            }
        }
        return list;
    }

    @Override
    public CancelRestoreBaseVO cancel(CancelDTO cancelDTO) throws XbbException{
        if (Objects.equals(cancelDTO.getBusinessType(),XbbRefTypeEnum.INVOICE.getCode())){
            return invoiceCancel(cancelDTO);
        }else if(Objects.equals(cancelDTO.getBusinessType(),XbbRefTypeEnum.PURCHASE_INVOICE.getCode())){
            return purchaseInvoiceCancel(cancelDTO);
        }else {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    private CancelRestoreBaseVO invoiceCancel(CancelDTO cancelDTO) throws XbbException{
        Integer businessType = XbbRefTypeEnum.INVOICE.getCode();
        UserVO loginUser = cancelDTO.getLoginUser();
        if (!Objects.equals(cancelDTO.getBusinessType(), businessType)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        if (!loginUser.getPermSet().contains(ProPermissionAliasEnum.INVOICE_CANCEL.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.INVOICE_CANCEL.getMemo()));
        }
        JSONObject hasReceivable = new JSONObject();
        String corpid = cancelDTO.getCorpid();
        String userId = cancelDTO.getUserId();
        Integer saasMark = SaasMarkEnum.SAAS.getCode();
        List<Long> dataIdList = cancelDTO.getDataIdList();
        Integer status = cancelDTO.getStatus();
        PaasFormDataEntityExt formDataEntityExt = formDataHelp.getFormDataWithTeam(corpid, saasMark, businessType, dataIdList.get(0));
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = Collections.singletonList(formDataEntityExt);
        //校验数据权限(团队权限&数据权限)
        VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, formDataEntityExt);
        boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
        if (!hasDataPermission){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.INVOICE_CANCEL.getMemo()));
        }
        Map<Long, PaasFormDataEntityExt> invoiceMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        paasFormDataEntityExtList.forEach(paasFormDataEntityExt -> invoiceMap.put(paasFormDataEntityExt.getId(), paasFormDataEntityExt));
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("invoiceIdIn", cancelDTO.getDataIdList());
        param.put(ParameterConstant.CORPID, cancelDTO.getCorpid());
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<InvoiceRelationshipEntity> invoiceRelationshipEntityList = invoiceRelationshipModel.findEntitys(param);
        Map<Long,List<InvoiceRelationshipEntity>> invoiceRelationshipMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> contractIds = new ArrayList<>();
        List<Long> refIds = new ArrayList<>();
        invoiceRelationshipEntityList.forEach(invoiceRelationshipEntity -> {
            saasSaveHelp.putInvoiceRelationshipMap(invoiceRelationshipMap,invoiceRelationshipEntity);
            if(!Objects.equals(invoiceRelationshipEntity.getContractId().intValue(),BasicConstant.ZERO)){
                contractIds.add(invoiceRelationshipEntity.getContractId());
            }
        });

        for (Long invoiceId : dataIdList) {
            PaasFormDataEntityExt paasFormDataEntityExt = invoiceMap.get(invoiceId);
            if (Objects.isNull(paasFormDataEntityExt)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
            }
            JSONObject dataJson = paasFormDataEntityExt.getData();
            JSONArray contractArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataJson,InvoiceEnum.CONTRACT_ID.getAttr(),new JSONArray());
            JSONArray paymentArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataJson,InvoiceEnum.PAYMENT_ID.getAttr(),new JSONArray());
            JSONArray paymentSheetArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataJson,InvoiceEnum.PAYMENT_SHEET_ID.getAttr(),new JSONArray());
            // 还原
            if (Objects.equals(status, BasicConstant.ZERO)) {
                // 判断发票金额
                boolean isHasPayment = false;
                boolean isHasPaymentSheet = false;
                boolean isPrePaymentSheet = false;
                boolean isPrePaymentSheetUnion = false;
                if(paymentSheetArray.size()>0){
                    isHasPaymentSheet = true;
                    refIds = JSONArray.parseArray(paymentSheetArray.toJSONString(),Long.class);
                }
                if(paymentArray.size()>0){
                    isHasPayment = true;
                    refIds = JSONArray.parseArray(paymentArray.toJSONString(),Long.class);
                }
                if(isHasPaymentSheet){
                    if(Objects.nonNull(dataJson)){
                        JSONArray jsonArray = dataJson.getJSONArray(InvoiceEnum.CONTRACT_ID.getAttr());
                        if(Objects.isNull(jsonArray)){
                            Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                            map.put(BasicConstant.IDIN,refIds);
                            map.put("corpid",corpid);
                            map.put("del",BasicConstant.ZERO);
                            List<PaymentSheetEntityExt> paymentSheetEntityExtList = paymentSheetModel.findEntitys(map);
                            if(CollectionsUtil.isNotEmpty(paymentSheetEntityExtList)) {
                                for(PaymentSheetEntityExt paymentSheetEntityExt : paymentSheetEntityExtList) {
                                    JSONObject data = paymentSheetEntityExt.getData();
                                    if (Objects.nonNull(data)) {
                                        String paymentSheetType = data.getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr());
                                        isPrePaymentSheet = Objects.equals(paymentSheetType, PaymentSheetTypeEnum.PREPAYMENT.getCode());
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                Double invoiceMoney = getDoubleOrDefaultFromFormData(paasFormDataEntityExt.getData(), InvoiceEnum.TOTAL_MONEY.getAttr(), 0D);
                Map<String,Object> relationMap = invoiceService.getRelationMapForJudgeMoney(isHasPaymentSheet,isPrePaymentSheet,isPrePaymentSheetUnion,isHasPayment, corpid, contractIds, refIds);
                if(CollectionsUtil.isNotEmpty(contractArray) || CollectionsUtil.isNotEmpty(paymentArray) || CollectionsUtil.isNotEmpty(paymentSheetArray)){
                    invoiceService.invoiceAmountJudgment(corpid, invoiceId, invoiceMoney, relationMap,BasicConstant.ZERO,BasicConstant.ZERO,BasicConstant.ONE,null);
                }
                BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
                boolQueryBuilder.filter(termsQuery("data."+ RefundEnum.INVOICES.getAttr(),Arrays.asList(invoiceId)));
                boolQueryBuilder.filter(termQuery(ParameterConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
                boolQueryBuilder.filter(termQuery(ParameterConstant.DEL, DelEnum.NORMAL.getDel()));
                List<PaasFormDataEntityExt> paasFormDataEntityExts = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_REFUND, boolQueryBuilder, PaasFormDataEntityExt.class, Arrays.asList(BasicConstant.ID,BasicConstant.DATA));
                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
                if(CollectionsUtil.isNotEmpty(paasFormDataEntityExts)) {
                    for(PaasFormDataEntityExt paasFormDataExt : paasFormDataEntityExts) {
                        JSONObject data = paasFormDataExt.getData();
                        if(Objects.nonNull(data)){
                            Object invoiceIdObj = data.get(RefundEnum.INVOICES.getAttr());
                            if (invoiceIdObj instanceof List) {
                                List invoiceIds = (List) invoiceIdObj;
                                invoiceIds.removeIf(id -> invoiceId.equals(Long.valueOf(id.toString())));
                                data.put(RefundEnum.INVOICES.getAttr(), invoiceIds);
                            }
                            Object invoiceNameObj = data.get(RefundEnum.INVOICES_LINKED_TEXT.getAttr());
                            if (invoiceNameObj instanceof List) {
                                List invoiceNames = (List) invoiceNameObj;
                                invoiceNames.remove(paasFormDataEntityExt.getSerialNo());
                                data.put(RefundEnum.INVOICES_LINKED_TEXT.getAttr(), invoiceNames);
                            }
                            updateDataEntityList.add(ExplainUtil.getUpdateData(paasFormDataExt.getId(),data,corpid));
                        }
                    }
                }
                if(CollectionsUtil.isNotEmpty(updateDataEntityList)) {
                    refundModel.updateBatch(updateDataEntityList, corpid);
                }
                refundInvoiceModel.deleteByInvoiceId(invoiceId, corpid);
            } else {
                Integer hasRed = getIntegerOrDefaultFromFormData(paasFormDataEntityExt.getData(), InvoiceEnum.HAS_RED.getAttr(), BasicConstant.ZERO);
                if (Objects.equals(hasRed, BasicConstant.ONE)) {
                    throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_216010);
                }
                Integer isRed = getIntegerOrDefaultFromFormData(paasFormDataEntityExt.getData(), InvoiceEnum.IS_RED.getAttr(), BasicConstant.ZERO);
                if(Objects.equals(isRed,BasicConstant.ONE)){
                    throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_216028);
                }
                Integer isCancel = getIntegerOrDefaultFromFormData(paasFormDataEntityExt.getData(), InvoiceEnum.IS_CANCEL.getAttr(), BasicConstant.ZERO);
                if(Objects.equals(isCancel,BasicConstant.ONE)){
                    throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_216029);
                }
                List<PaasFormDataEntityExt> paasFormDataEntityExts = paymentService.getReceivablesBySourceIdIn(corpid, ModelTypeEnum.INVOICE.getXbbRefTypeEnum().getCode(),Collections.singletonList(paasFormDataEntityExt.getId()));
                if(CollectionsUtil.isNotEmpty(paasFormDataEntityExts)) {
                    hasReceivable.put(BasicConstant.HASRECEIVABLES, I18nMessageUtil.getMessage(ErrorMessageConstant.RED_INVOICE_HAS_RECEIVABLES));
                }
            }

        }
        List<String> invoiceNo = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> invoiceIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
            Map<Long,Double> contractMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long,Double> paymentRefMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long,Double> paymentSheetRefMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            // 更新其他业务的开票金额和未开票金额
            List<Long> contractIdList = FastJsonHelper.getJsonArrOrDefaultFromFormData(paasFormDataEntityExt.getData(), InvoiceEnum.CONTRACT_ID.getAttr(), new JSONArray()).toJavaList(Long.class);
            List<Long> paymentIdList = FastJsonHelper.getJsonArrOrDefaultFromFormData(paasFormDataEntityExt.getData(), InvoiceEnum.PAYMENT_ID.getAttr(), new JSONArray()).toJavaList(Long.class);
            List<Long> paymentSheetIdList = FastJsonHelper.getJsonArrOrDefaultFromFormData(paasFormDataEntityExt.getData(), InvoiceEnum.PAYMENT_SHEET_ID.getAttr(), new JSONArray()).toJavaList(Long.class);

            List<InvoiceRelationshipEntity> invoiceRelationshipEntities = invoiceRelationshipMap.get(paasFormDataEntityExt.getId());
            saasUpdateHelp.getInvoiceRefMap(contractMap,paymentRefMap,paymentSheetRefMap,invoiceRelationshipEntities,null,null,null);
            InvoiceCancelOrRestorePojo invoiceCancelOrRestorePojo = new InvoiceCancelOrRestorePojo(contractIdList,paymentIdList,paymentSheetIdList,contractMap,paymentRefMap,paymentSheetRefMap);
            if(CollectionsUtil.isNotEmpty(contractIdList) && CollectionsUtil.isEmpty(paymentIdList) && CollectionsUtil.isEmpty(paymentSheetIdList)){
                invoiceService.updateInvoiceMoney(corpid,invoiceCancelOrRestorePojo, cancelDTO.getStatus(),BasicConstant.ZERO,XbbRefTypeEnum.CONTRACT.getCode());
            }else if(CollectionsUtil.isNotEmpty(paymentIdList) && CollectionsUtil.isNotEmpty(contractIdList) && CollectionsUtil.isEmpty(paymentSheetIdList)){
                invoiceService.updateInvoiceMoney(corpid,invoiceCancelOrRestorePojo, cancelDTO.getStatus(),BasicConstant.ZERO,XbbRefTypeEnum.PAYMENT.getCode());
            }else if(CollectionsUtil.isNotEmpty(paymentSheetIdList) && CollectionsUtil.isEmpty(paymentIdList)){
                invoiceService.updateInvoiceMoney(corpid,invoiceCancelOrRestorePojo, cancelDTO.getStatus(),BasicConstant.ZERO,XbbRefTypeEnum.PAYMENT_SHEET.getCode());
            }
            //当是单个作废的时候进行单个更新
            if(cancelDTO.getSingle() !=null && Objects.equals(1,cancelDTO.getSingle()) && CollectionsUtil.isNotEmpty(cancelDTO.getDataIdList()) && cancelDTO.getDataIdList().size()==1){
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(InvoiceEnum.IS_CANCEL.getAttr(),cancelDTO.getStatus());
                proUpdateHelp.update(cancelDTO.getBusinessType(),cancelDTO.getCorpid(),cancelDTO.getDataIdList().get(0), jsonObject);
            }else {
                proUpdateHelp.updateByIds(cancelDTO.getBusinessType(),cancelDTO.getCorpid(),cancelDTO.getDataIdList(),InvoiceEnum.IS_CANCEL.getAttr(),cancelDTO.getStatus());
            }
            invoiceRelationshipModel.updateIsCancel(cancelDTO.getStatus(), param);
            InvoiceEntityExt invoiceEntityExt = new InvoiceEntityExt();
            BeanUtil.copyProperties(paasFormDataEntityExt, invoiceEntityExt);
            Long dataId = invoiceEntityExt.getId();
            if (Objects.equals(cancelDTO.getStatus(), 1)) {
                // 发票作废消息推送
                List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.INVOICE_INVALIDATION.getCode(), PushTypeEnum.INVOICE_INVALIDATION.getSubCode(), loginUser, invoiceEntityExt);
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(invoiceEntityExt.getAppId(), invoiceEntityExt.getMenuId(), invoiceEntityExt.getFormId(), dataId, Collections.singletonList(dataId), saasMark, cancelDTO.getBusinessType(), cancelDTO.getBusinessType());
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(dataId), 0, null, I18nMessageUtil.getMessage(InvoicePushConstant.INVOICE_INVALIDATION_TITLE), String.format(I18nMessageUtil.getMessage(InvoicePushConstant.INVOICE_INVALIDATION_CONTENT), cancelDTO.getLoginUserName(), invoiceEntityExt.getSerialNo()),  null, options);
                baseProducer.sendMessage(PushTypeEnum.INVOICE_INVALIDATION, messageRabbitMqDTO);
            } else {
                // 发票还原消息推送
                List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.INVOICE_REDUCTION.getCode(), PushTypeEnum.INVOICE_REDUCTION.getSubCode(), loginUser, invoiceEntityExt);
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(invoiceEntityExt.getAppId(), invoiceEntityExt.getMenuId(), invoiceEntityExt.getFormId(), dataId, Collections.singletonList(dataId), saasMark, cancelDTO.getBusinessType(), cancelDTO.getBusinessType());
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(dataId), 0, null, I18nMessageUtil.getMessage(InvoicePushConstant.INVOICE_REDUCTION_TITLE), String.format(I18nMessageUtil.getMessage(InvoicePushConstant.INVOICE_REDUCTION_CONTENT), cancelDTO.getLoginUserName(), invoiceEntityExt.getSerialNo()), null, options);
                baseProducer.sendMessage(PushTypeEnum.INVOICE_REDUCTION, messageRabbitMqDTO);
            }
            invoiceNo.add(paasFormDataEntityExt.getSerialNo());
            invoiceIds.add(dataId);
        }
        // 日志
        OperateTypeEnum operateTypeEnum = IsCancelEnum.getIsCancelByCode(status);
        String nameStr = StringUtils.join(invoiceNo, "，");
        String userName = cancelDTO.getLoginUserName();

        if(invoiceIds.size() > 1){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ARCHIVE_FORM_DATA), userName, operateTypeEnum.getName(), nameStr);
            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            InfoArrPojo infoArrPojo = new InfoArrPojo();
            infoArrPojo.setTitle(XbbRefTypeEnum.INVOICE.getName());
            infoArrPojo.setContent(nameStr);
            infoArrPojoList.add(infoArrPojo);
            mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.INVOICE, operateTypeEnum,
                    "", "", memo, cancelDTO.getHttpHeader());
        } else if(Objects.equals(invoiceIds.size(), 1)){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ARCHIVE_FORM_DATA), userName, operateTypeEnum.getName(), nameStr);
            mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.INVOICE, operateTypeEnum,
                    invoiceIds.get(0).toString(), nameStr, memo, cancelDTO.getHttpHeader());
        }
        CancelRestoreBaseVO cancelRestoreBaseVO = new CancelRestoreBaseVO();
        if(hasReceivable.containsKey(BasicConstant.HASRECEIVABLES)){
            cancelRestoreBaseVO.setSpecialMsg(hasReceivable);
        }
        return cancelRestoreBaseVO;
    }

    private CancelRestoreBaseVO purchaseInvoiceCancel(CancelDTO cancelDTO) throws XbbException{
        Integer businessType = XbbRefTypeEnum.PURCHASE_INVOICE.getCode();
        UserVO loginUser = cancelDTO.getLoginUser();
        if (!Objects.equals(cancelDTO.getBusinessType(), businessType)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        if (!loginUser.getPermSet().contains(ProPermissionAliasEnum.PURCHASE_INVOICE_CANCEL.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.INVOICE_CANCEL.getMemo()));
        }
        String corpid = cancelDTO.getCorpid();
        String userId = cancelDTO.getUserId();
        Integer saasMark = SaasMarkEnum.SAAS.getCode();
        List<Long> dataIdList = cancelDTO.getDataIdList();
        Integer status = cancelDTO.getStatus();
        PaasFormDataEntityExt formDataEntityExt = formDataHelp.getFormDataWithTeam(corpid, saasMark, businessType, dataIdList.get(0));
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = Collections.singletonList(formDataEntityExt);
        //作废还原只有单条操作,无需判单条还是批量
        //校验数据权限(团队权限&数据权限)
        VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, formDataEntityExt);
        boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
        if (!hasDataPermission){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.INVOICE_CANCEL.getMemo()));
        }
        Map<Long, PaasFormDataEntityExt> purchaseInvoiceMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        paasFormDataEntityExtList.forEach(paasFormDataEntityExt -> purchaseInvoiceMap.put(paasFormDataEntityExt.getId(), paasFormDataEntityExt));
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("purchaseInvoiceIdIn", cancelDTO.getDataIdList());
        param.put(ParameterConstant.CORPID, cancelDTO.getCorpid());
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<PurchaseInvoiceRelationshipEntity> purchaseInvoiceRelationshipEntityList = purchaseInvoiceRelationshipModel.findEntitys(param);
        Map<Long,List<PurchaseInvoiceRelationshipEntity>> purchaseInvoiceRelationshipMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> purchaseIds = new ArrayList<>();
        List<Long> refIds = new ArrayList<>();
        purchaseInvoiceRelationshipEntityList.forEach(invoiceRelationshipEntity -> {
            saasSaveHelp.putPurchaseInvoiceRelationshipMap(purchaseInvoiceRelationshipMap,invoiceRelationshipEntity);
            if(!Objects.equals(invoiceRelationshipEntity.getPurchaseId().intValue(),BasicConstant.ZERO)){
                purchaseIds.add(invoiceRelationshipEntity.getPurchaseId());
            }
        });

        for(Long invoiceId : dataIdList){
            PaasFormDataEntityExt paasFormDataEntityExt = purchaseInvoiceMap.get(invoiceId);
            if(Objects.isNull(paasFormDataEntityExt)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
            }
            JSONObject dataJson = paasFormDataEntityExt.getData();
            JSONArray purchaseArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataJson, PurchaseInvoiceEnum.PURCHASE_ID.getAttr(),new JSONArray());
            JSONArray payPlanArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataJson, PurchaseInvoiceEnum.PAY_PLAN_ID.getAttr(),new JSONArray());
            JSONArray paySheetArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataJson,PurchaseInvoiceEnum.PAY_SHEET_ID.getAttr(),new JSONArray());
            //还原
            if (Objects.equals(status, BasicConstant.ZERO)) {
                // 判断发票金额
                boolean isHasPayPlan = false;
                boolean isHasPaySheet = false;
                boolean isPrePaySheet = false;
                boolean isPrePaySheetUnion = false;
                if(paySheetArray.size()>0){
                    isHasPaySheet = true;
                    refIds = JSONArray.parseArray(paySheetArray.toJSONString(),Long.class);
                }
                if(payPlanArray.size()>0){
                    isHasPayPlan = true;
                    refIds = JSONArray.parseArray(payPlanArray.toJSONString(),Long.class);
                }
                if(isHasPaySheet){
                    if(Objects.nonNull(dataJson)){
                        JSONArray jsonArray = dataJson.getJSONArray(PurchaseInvoiceEnum.PURCHASE_ID.getAttr());
                        if(Objects.isNull(jsonArray)){
                            Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                            map.put(BasicConstant.IDIN,refIds);
                            map.put("corpid",corpid);
                            map.put("del",BasicConstant.ZERO);
                            List<PayPlanSheetEntityExt> paySheetEntityExtList = paySheetModel.findEntitys(map);
                            if(CollectionsUtil.isNotEmpty(paySheetEntityExtList)) {
                                for(PayPlanSheetEntityExt paySheetEntityExt : paySheetEntityExtList) {
                                    JSONObject data = paySheetEntityExt.getData();
                                    if (Objects.nonNull(data)) {
                                        String paySheetType = data.getString(PaySheetEnum.PAY_SHEET_TYPE.getAttr());
                                        isPrePaySheet = Objects.equals(paySheetType, PaySheetTypeEnum.PREPAY.getCode());
                                        break;
                                    }
                                }
                                if(paySheetEntityExtList.size()>BasicConstant.ONE){
                                    isPrePaySheetUnion = true;
                                }
                            }
                        }
                    }
                }
                Double invoiceMoney = getDoubleOrDefaultFromFormData(paasFormDataEntityExt.getData(),PurchaseInvoiceEnum.TOTAL_MONEY.getAttr(), 0D);
                Map<String,Object> relationMap = purchaseInvoiceService.getRelationMapForJudgeMoney(isHasPaySheet,isPrePaySheet,isPrePaySheetUnion,isHasPayPlan,corpid, purchaseIds, refIds);
                if(CollectionsUtil.isNotEmpty(purchaseArray) || CollectionsUtil.isNotEmpty(payPlanArray) || CollectionsUtil.isNotEmpty(paySheetArray)){
                    purchaseInvoiceService.invoiceAmountJudgment(corpid, invoiceId, invoiceMoney, relationMap,BasicConstant.ZERO,BasicConstant.ZERO,BasicConstant.ONE,null);
                }
                //TODO 采购退货
                BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
                boolQueryBuilder.filter(termsQuery("data."+ ReturnedPurchaseEnum.INVOICES.getAttr(),Arrays.asList(invoiceId)));
                boolQueryBuilder.filter(termQuery(ParameterConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
                boolQueryBuilder.filter(termQuery(ParameterConstant.DEL, DelEnum.NORMAL.getDel()));
                List<PaasFormDataEntityExt> paasFormDataEntityExts = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_RETURNED_PURCHASE, boolQueryBuilder, PaasFormDataEntityExt.class, Arrays.asList(BasicConstant.ID,BasicConstant.DATA));
                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
                if(CollectionsUtil.isNotEmpty(paasFormDataEntityExts)) {
                    for(PaasFormDataEntityExt paasFormDataExt : paasFormDataEntityExts) {
                        JSONObject data = paasFormDataExt.getData();
                        if(Objects.nonNull(data)){
                            Object invoiceIdObj = data.get(ReturnedPurchaseEnum.INVOICES.getAttr());
                            if (invoiceIdObj instanceof List) {
                                List invoiceIds = (List) invoiceIdObj;
                                invoiceIds.removeIf(id -> invoiceId.equals(Long.valueOf(id.toString())));
                                data.put(ReturnedPurchaseEnum.INVOICES.getAttr(), invoiceIds);
                            }
                            Object invoiceNameObj = data.get(ReturnedPurchaseEnum.INVOICES_LINKED_TEXT.getAttr());
                            if (invoiceNameObj instanceof List) {
                                List invoiceNames = (List) invoiceNameObj;
                                invoiceNames.remove(paasFormDataEntityExt.getSerialNo());
                                data.put(ReturnedPurchaseEnum.INVOICES_LINKED_TEXT.getAttr(), invoiceNames);
                            }
                            updateDataEntityList.add(ExplainUtil.getUpdateData(paasFormDataExt.getId(),data,corpid));
                        }
                    }
                }
                if(CollectionsUtil.isNotEmpty(updateDataEntityList)) {
                    returnedPurchaseModel.updateBatch(updateDataEntityList, corpid);
                }
                returnedPurchaseInvoiceModel.deleteByInvoiceId(invoiceId, corpid);
            }else {
                Integer hasRed = getIntegerOrDefaultFromFormData(paasFormDataEntityExt.getData(),PurchaseInvoiceEnum.HAS_RED.getAttr(), BasicConstant.ZERO);
                if (Objects.equals(hasRed, BasicConstant.ONE)) {
                    throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_217005);
                }
                Integer isRed = getIntegerOrDefaultFromFormData(paasFormDataEntityExt.getData(),PurchaseInvoiceEnum.IS_RED.getAttr(), BasicConstant.ZERO);
                if(Objects.equals(isRed,BasicConstant.ONE)){
                    throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_217006);
                }
                Integer isCancel = getIntegerOrDefaultFromFormData(paasFormDataEntityExt.getData(),PurchaseInvoiceEnum.IS_CANCEL.getAttr(), BasicConstant.ZERO);
                if(Objects.equals(isCancel,BasicConstant.ONE)){
                    throw new XbbException(InvoiceErrorCodeEnum.API_ERROR_217007);
                }
            }
        }
        List<String> purchaseInvoiceNo = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> purchaseInvoiceIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
            Map<Long,Double> purchaseMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long,Double> payPlanRefMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long,Double> paySheetRefMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            // 更新其他业务的开票金额和未开票金额
            List<Long> purchaseIdList = FastJsonHelper.getJsonArrOrDefaultFromFormData(paasFormDataEntityExt.getData(),PurchaseInvoiceEnum.PURCHASE_ID.getAttr(), new JSONArray()).toJavaList(Long.class);
            List<Long> payPlanIdList = FastJsonHelper.getJsonArrOrDefaultFromFormData(paasFormDataEntityExt.getData(), PurchaseInvoiceEnum.PAY_PLAN_ID.getAttr(), new JSONArray()).toJavaList(Long.class);
            List<Long> paySheetIdList = FastJsonHelper.getJsonArrOrDefaultFromFormData(paasFormDataEntityExt.getData(),PurchaseInvoiceEnum.PAY_SHEET_ID.getAttr(), new JSONArray()).toJavaList(Long.class);

            List<PurchaseInvoiceRelationshipEntity> purchaseInvoiceRelationshipEntities = purchaseInvoiceRelationshipMap.get(paasFormDataEntityExt.getId());
            saasUpdateHelp.getPurchaseInvoiceRefMap(purchaseMap,payPlanRefMap,paySheetRefMap,purchaseInvoiceRelationshipEntities,null,null,null);
            PurchaseInvoiceCancelOrRestorePojo purchaseInvoiceCancelOrRestorePojo = new PurchaseInvoiceCancelOrRestorePojo(purchaseIdList,payPlanIdList,paySheetIdList,purchaseMap,payPlanRefMap,paySheetRefMap);
            if(CollectionsUtil.isNotEmpty(purchaseIdList) && CollectionsUtil.isEmpty(payPlanIdList) && CollectionsUtil.isEmpty(paySheetIdList)){
                purchaseInvoiceService.updateInvoiceMoney(corpid,purchaseInvoiceCancelOrRestorePojo, cancelDTO.getStatus(),BasicConstant.ZERO,XbbRefTypeEnum.PURCHASE.getCode());
            }else if(CollectionsUtil.isNotEmpty(payPlanIdList) && CollectionsUtil.isNotEmpty(purchaseIdList) && CollectionsUtil.isEmpty(paySheetIdList)){
                purchaseInvoiceService.updateInvoiceMoney(corpid,purchaseInvoiceCancelOrRestorePojo, cancelDTO.getStatus(),BasicConstant.ZERO,XbbRefTypeEnum.PAY_PLAN.getCode());
            }else if(CollectionsUtil.isNotEmpty(paySheetIdList) && CollectionsUtil.isEmpty(payPlanIdList)){
                purchaseInvoiceService.updateInvoiceMoney(corpid,purchaseInvoiceCancelOrRestorePojo, cancelDTO.getStatus(),BasicConstant.ZERO,XbbRefTypeEnum.PAY_SHEET.getCode());
            }
            //当是单个作废的时候进行单个更新
            if(cancelDTO.getSingle() !=null && Objects.equals(1,cancelDTO.getSingle()) && CollectionsUtil.isNotEmpty(cancelDTO.getDataIdList()) && cancelDTO.getDataIdList().size()==1){
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(PurchaseInvoiceEnum.IS_CANCEL.getAttr(),cancelDTO.getStatus());
                proUpdateHelp.update(cancelDTO.getBusinessType(),cancelDTO.getCorpid(),cancelDTO.getDataIdList().get(0), jsonObject);
            }else {
                proUpdateHelp.updateByIds(cancelDTO.getBusinessType(),cancelDTO.getCorpid(),cancelDTO.getDataIdList(),PurchaseInvoiceEnum.IS_CANCEL.getAttr(),cancelDTO.getStatus());
            }
            purchaseInvoiceRelationshipModel.updateIsCancel(cancelDTO.getStatus(),param);
            PurchaseInvoiceEntityExt purchaseInvoiceEntityExt = new PurchaseInvoiceEntityExt();
            BeanUtil.copyProperties(paasFormDataEntityExt, purchaseInvoiceEntityExt);
            Long dataId = purchaseInvoiceEntityExt.getId();
            if (Objects.equals(cancelDTO.getStatus(), 1)) {
                // 发票作废消息推送
                List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.PURCHASE_INVOICE_INVALIDATION.getCode(), PushTypeEnum.PURCHASE_INVOICE_INVALIDATION.getSubCode(), loginUser, purchaseInvoiceEntityExt);
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(purchaseInvoiceEntityExt.getAppId(), purchaseInvoiceEntityExt.getMenuId(), purchaseInvoiceEntityExt.getFormId(), dataId, Collections.singletonList(dataId), saasMark, cancelDTO.getBusinessType(), cancelDTO.getBusinessType());
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(dataId), 0, null, I18nMessageUtil.getMessage(InvoicePushConstant.PURCHASE_INVOICE_INVALIDATION_TITLE), String.format(I18nMessageUtil.getMessage(InvoicePushConstant.PURCHASE_INVOICE_INVALIDATION_CONTENT), cancelDTO.getLoginUserName(), purchaseInvoiceEntityExt.getSerialNo()),  null, options);
                baseProducer.sendMessage(PushTypeEnum.PURCHASE_INVOICE_INVALIDATION, messageRabbitMqDTO);
            } else {
                // 发票还原消息推送
                List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.PURCHASE_INVOICE_REDUCTION.getCode(), PushTypeEnum.PURCHASE_INVOICE_REDUCTION.getSubCode(), loginUser, purchaseInvoiceEntityExt);
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(purchaseInvoiceEntityExt.getAppId(), purchaseInvoiceEntityExt.getMenuId(), purchaseInvoiceEntityExt.getFormId(), dataId, Collections.singletonList(dataId), saasMark, cancelDTO.getBusinessType(), cancelDTO.getBusinessType());
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(dataId), 0, null, I18nMessageUtil.getMessage(InvoicePushConstant.PURCHASE_INVOICE_REDUCTION_TITLE), String.format(I18nMessageUtil.getMessage(InvoicePushConstant.PURCHASE_INVOICE_REDUCTION_CONTENT), cancelDTO.getLoginUserName(), purchaseInvoiceEntityExt.getSerialNo()), null, options);
                baseProducer.sendMessage(PushTypeEnum.PURCHASE_INVOICE_REDUCTION, messageRabbitMqDTO);
            }
            purchaseInvoiceNo.add(paasFormDataEntityExt.getSerialNo());
            purchaseInvoiceIds.add(dataId);
        }
        OperateTypeEnum operateTypeEnum = IsCancelEnum.getIsCancelByCode(status);
        String nameStr = StringUtils.join(purchaseInvoiceNo, "，");
        String userName = cancelDTO.getLoginUserName();

        if(purchaseInvoiceIds.size() > 1){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ARCHIVE_FORM_DATA), userName, operateTypeEnum.getName(), nameStr);
            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            InfoArrPojo infoArrPojo = new InfoArrPojo();
            infoArrPojo.setTitle(XbbRefTypeEnum.PURCHASE_INVOICE.getName());
            infoArrPojo.setContent(nameStr);
            infoArrPojoList.add(infoArrPojo);
            mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.PURCHASE_INVOICE, operateTypeEnum,
                    "", "", memo, cancelDTO.getHttpHeader());
        } else if(Objects.equals(purchaseInvoiceIds.size(), 1)){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ARCHIVE_FORM_DATA), userName, operateTypeEnum.getName(), nameStr);
            mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PURCHASE_INVOICE, operateTypeEnum,
                    purchaseInvoiceIds.get(0).toString(), nameStr, memo, cancelDTO.getHttpHeader());
        }
        return new CancelRestoreBaseVO();
    }
    @Override
    public BaseVO online(OnlineDTO onlineDTO) throws XbbException {
        Integer businessType = onlineDTO.getBusinessType();
        if (Objects.equals(businessType, XbbRefTypeEnum.MARKETING_ACTIVITY_MANAGEMENT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PROMOTION_ACTIVITY_MANAGEMENT.getCode())) {
            return marketingManagementService.online(onlineDTO);
        }
        String corpid = onlineDTO.getCorpid();
        // 上下架 1上架0下架
        Integer online = onlineDTO.getOnline();
        if (!onlineDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PRODUCT_ONLINE.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.PRODUCT_ONLINE.getMemo()));
        }
        List<Long> resultProductIds = onlineDTO.getDataIdList();
        if(resultProductIds != null){
            resultProductIds.addAll(getSubProduct(corpid,onlineDTO.getDataIdList()));
        }
        //父子产品更新
        JSONObject obj = new JSONObject();
        obj.put(ProductEnum.ONLINE.getAttr(), online);
        if (Objects.equals(online, 1)) {
            obj.put(ProductEnum.ONLINE_TIME.getAttr(), DateTimeUtil.getInt());
        } else {
            obj.put(ProductEnum.ONLINE_TIME.getAttr(), null);
        }
        proUpdateHelp.updateByIds(businessType,corpid,resultProductIds,obj);

        // 产品上下架日志
        String userId = onlineDTO.getUserId();
        String userName = onlineDTO.getLoginUserName();
        //查询产品名称
        Map<String, String> productNoAndName= new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        BoolQueryBuilder productBuilder = boolQuery();
        // 添加corpid,formId,del
        productBuilder.filter(termQuery("corpid.keyword", corpid));
        productBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        // 只记录父产品的上下架变化
        productBuilder.filter(termQuery(ProductEnum.getAttrConnectData(ProductEnum.PARENT_ID), 0));
        productBuilder.filter(termsQuery(StringConstant.DATA_ID, resultProductIds));
        List<String> field = new ArrayList<>();
        field.add(StringConstant.DATA_ID);
        field.add(StringConstant.FORM_ID);
        field.add(ProductEnum.getAttrConnectData(ProductEnum.PRODUCT_NO));
        field.add(ProductEnum.getAttrConnectData(ProductEnum.NAME));
        List<PaasFormDataEntityExt> productList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PRODUCT, productBuilder, PaasFormDataEntityExt.class, field);
        for(PaasFormDataEntityExt product : productList){
            JSONObject data = product.getData();
            String productNo = FastJsonHelper.getStringOrDefaultFromFormData(data, ProductEnum.PRODUCT_NO.getAttr(), "");
            String name = FastJsonHelper.getStringOrDefaultFromFormData(data, ProductEnum.NAME.getAttr(), "");
            productNoAndName.put(productNo, name);
        }
        List<String> list = new ArrayList<>();
        Iterator<String> iterator = productNoAndName.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String value = productNoAndName.get(key);
            if(StringUtil.isEmpty(value)){
                list.add(key);
            } else {
                StringBuilder sb = new StringBuilder();
                sb.append(value).append("（").append(key).append("）");
                list.add(sb.toString());
            }
        }
        String nameStr = StringUtils.join(list, "，");
        OperateTypeEnum operateTypeEnum = Objects.equals(online, 1) ? OperateTypeEnum.ONLINE : OperateTypeEnum.OFFLINE;
        if(productList.size() > 1){
            String batchOnline = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_ONLINE_FORM_DETAIL), userName, XbbRefTypeEnum.PRODUCT.getName(), productList.size());
            String batchOffline = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_OFFLINE_FORM_DETAIL), userName, XbbRefTypeEnum.PRODUCT.getName(), productList.size());
            String memo = Objects.equals(online, 1) ? batchOnline : batchOffline;
            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            InfoArrPojo infoArrPojo = new InfoArrPojo();
            infoArrPojo.setTitle(ProductEnum.PRODUCT_NO.getAttrName());
            infoArrPojo.setContent(nameStr);
            infoArrPojoList.add(infoArrPojo);
            mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.PRODUCT, operateTypeEnum,
                    "", "", memo, onlineDTO.getHttpHeader());
        } else if (Objects.equals(productList.size(), 1)){
            String onlyOnline = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ONLINE), userName, XbbRefTypeEnum.PRODUCT.getName(), nameStr);
            String onlyOffline = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_OFFLINE), userName, XbbRefTypeEnum.PRODUCT.getName(), nameStr);
            String memo = Objects.equals(online, 1) ? onlyOnline : onlyOffline;
            mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PRODUCT, operateTypeEnum,
                    productList.get(0).getDataId().toString(), nameStr, memo, onlineDTO.getHttpHeader());
        }
        return new BaseVO();
    }
    @Override
    public TeamBatchVO addMainUser(AddMainUserDTO addMainUserDTO) throws XbbException {
        TeamBatchVO teamBatchVO = new TeamBatchVO();

        int size = addMainUserDTO.getDataIdList().size();
        if (size > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }
        String corpid = addMainUserDTO.getCorpid();
        List<Long> dataIdList = addMainUserDTO.getDataIdList();
        Integer businessType = addMainUserDTO.getBusinessType();
        Long formId = addMainUserDTO.getFormId();
        UserVO loginUser = addMainUserDTO.getLoginUser();
        //数据权限校验
        List<TeamBatchPojo> teamBatchPojos = checkDataPermission4Share(dataIdList, businessType, formId, addMainUserDTO.getSaasMark(), corpid, loginUser, UserTeamOperateTagEnum.ADD_MAIN);

        // 批量的数据锁
        String redisPrefix = teamDataHelp.getRedisPrefix(addMainUserDTO.getSaasMark(), addMainUserDTO.getBusinessType());
        List<Long> lackIdList = dataLocking(addMainUserDTO.getDataIdList(), addMainUserDTO.getCorpid(), redisPrefix);

        List<TeamBatchPojo> teamBatchPojos4Approval = teamHelp.checkDataIsApproval(addMainUserDTO.getDataIdList(), addMainUserDTO.getCorpid(), addMainUserDTO.getFormId(), addMainUserDTO.getSaasMark(), addMainUserDTO.getBusinessType(), UserTeamOperateTagEnum.ADD_MAIN);
        if(CollectionsUtil.isNotEmpty(teamBatchPojos4Approval)){
            teamBatchPojos.addAll(teamBatchPojos4Approval);
        }
        boolean fromCheckRepeatForm = Boolean.TRUE.equals(addMainUserDTO.getFromCheckRepeatForm());
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(addMainUserDTO, teamVerifyDTO);
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setCreatorId(addMainUserDTO.getUserId());
        teamVerifyDTO.setIsNew(false);
        teamVerifyDTO.setDataId(addMainUserDTO.getDataIdList());
        teamVerifyDTO.setNewAddMainUserList(new HashSet<>(addMainUserDTO.getUserIdList()));
        teamVerifyDTO.setBatchTag(1);

        teamVerifyDTO.setLoginUser(addMainUserDTO.getLoginUser());
        teamVerifyDTO.setBatchTag(Constant.ONE);
        teamVerifyDTO.setFromCheckRepeatForm(fromCheckRepeatForm);
        teamBatchPojos.addAll(teamDataHelp.save(teamVerifyDTO));

        // 封装批量因为被加锁不能操作的报错处理
        if (CollectionsUtil.isNotEmpty(lackIdList)) {
            Map<Long, String> nameOrSeriNoMap = new HashMap<>();
            userTeamHelp.getEntityMap(teamVerifyDTO.getBusinessType(), lackIdList, teamVerifyDTO.getCorpid(), nameOrSeriNoMap, teamVerifyDTO.getSaasMark());
            List<String> lackName = new ArrayList<>(lackIdList.size());
            for (Long id : lackIdList) {
                lackName.add(nameOrSeriNoMap.getOrDefault(id, ""));
            }
            addMainUserDTO.getDataIdList().removeAll(lackIdList);
            commonHelp.batchSameErrorPackage(lackName, UserTeamOperateTagEnum.ADD_MAIN.getName(),
                    UserTeamErrorCodeEnum.API_ERROR_271020.getCode(), UserTeamErrorCodeEnum.API_ERROR_271020.getMsg(), teamBatchPojos);
        }

        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
            commonHelp.batchFailMsg(teamBatchPojos, size, teamBatchVO);

            for (TeamBatchPojo teamBatchPojo : teamBatchPojos) {
                dataIdList.remove(teamBatchPojo.getDataId());
            }
        }

        if(fromCheckRepeatForm) {
            checkJoinTeam(addMainUserDTO);
        }

        return teamBatchVO;
        /*TeamBatchVO teamBatchVO = new TeamBatchVO();
        List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();
        List<Long> dataIdList = addMainUserDTO.getDataIdList();
        Integer dataIdSize = dataIdList.size();
        if (dataIdSize > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }
        List<Long> originalIds = new ArrayList<>(dataIdList);
        String corpid = addMainUserDTO.getCorpid();
        List<String> userIdList = addMainUserDTO.getUserIdList();
        Integer businessType = addMainUserDTO.getBusinessType();
        Integer isMain = BasicConstant.MAIN_USER;

        Map<Long, String> nameOrNoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, PaasFormDataEntityExt> entityMap = getEntityMap(businessType, dataIdList, corpid, nameOrNoMap);

        String redisPrefix = getRedisPrefix(businessType);
        List<Long> lackIdList = dataLocking(dataIdList,corpid, redisPrefix);

        IndexTypeEnum indexTypeTeamEnum = indexTypeModel.getTeamIndexType(corpid, businessType);
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termsQuery(SubFormTransferEnum.getEsAttrByIndexTypeAndDbAttr(indexTypeTeamEnum, StringConstant.DATA_ID), dataIdList));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        List<PaasFormDataEntity> userTeamList = esHelper.findByScroll(indexTypeTeamEnum, boolQueryBuilder, PaasFormDataEntity.class, Arrays.asList("id", SubFormTransferEnum.getFieldAttrByIndexTypeAndDbAttr(indexTypeTeamEnum, StringConstant.DATA_ID), SubFormTransferEnum.getFieldAttrByIndexTypeAndDbAttr(indexTypeTeamEnum, ParameterConstant.IS_MAIN), SubFormTransferEnum.getFieldAttrByIndexTypeAndDbAttr(indexTypeTeamEnum, ParameterConstant.USER_ID)));
        List<UserTeamEntity> userTeamEntities = (List<UserTeamEntity>) transferSubFormHelper.transferFormDataToUserTeamList(indexTypeTeamEnum, userTeamList);
        List<String> teamUserList = new ArrayList<>();
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coopUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<String> allUserIds = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        allUserIds.addAll(userIdList);
        Map<String,UserTeamEntity> userTeamEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (UserTeamEntity entity : userTeamEntities) {
            allUserIds.add(entity.getUserId());
            userTeamEntityMap.put(entity.getDataId() + "_" + entity.getUserId(),entity);
            teamUserList.add(entity.getDataId() + "_" + entity.getUserId());
            if (Objects.equals(entity.getIsMain(), BasicConstant.MAIN_USER)) {
                List<String> mainUserIds = new ArrayList<>();
                if (mainUserMap.containsKey(entity.getDataId())) {
                    mainUserIds = mainUserMap.get(entity.getDataId());
                }
                mainUserIds.add(entity.getUserId());
                mainUserMap.put(entity.getDataId(), mainUserIds);
            }
            if (Objects.equals(entity.getIsMain(), BasicConstant.COOP_USER)) {
                List<String> coUserIds = new ArrayList<>();
                if (coopUserMap.containsKey(entity.getDataId())) {
                    coUserIds = coopUserMap.get(entity.getDataId());
                }
                coUserIds.add(entity.getUserId());
                coopUserMap.put(entity.getDataId(), coUserIds);
            }
        }
        Map<String, FieldAttrEntity> explainMap;
        if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
            WorkOrderExplainEntityExt workOrderExplain = workOrderExplainModel.getByFormId(addMainUserDTO.getFormId(), addMainUserDTO.getCorpid());
            if (Objects.isNull(workOrderExplain)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            explainMap = ExplainUtil.getExplainMap(workOrderExplain.getExplains(), FieldTypeEnum.OWNERID.getAlias());
        } else {
            PaasFormExplainEntity explain = paasFormExplainModel.getByFormId(addMainUserDTO.getFormId(), addMainUserDTO.getCorpid());
            if (Objects.isNull(explain)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            explainMap = ExplainUtil.getExplainMap(explain.getExplains(), FieldTypeEnum.OWNERID.getAlias());
        }
        FieldAttrEntity mainUserField = explainMap.getOrDefault(FieldTypeEnum.OWNERID.getAlias(), new FieldAttrEntity());

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(addMainUserDTO, handlerExplainDTO);

        List<UserEntity> userList = userModel.getByUserIdIn(corpid,new ArrayList<>(allUserIds),false);
        Map<String, UserEntity> userEntityMap = new HashMap<>(userList.size());
        userList.forEach(item -> userEntityMap.put(item.getUserId(), item));
        List<String> businessNameList = new ArrayList<>();
        Set<String> failAddNameList = new HashSet<>();

        Map<String, List<Long>> userIdAndIdsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> idAndUserIdsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<UserTeamEntity> insertBatchList = new ArrayList<>();
        List<UserTeamEntity> delBatchList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (Long id : dataIdList){
            PaasFormDataEntityExt entityExt = entityMap.get(id);
            if (Objects.isNull(entityExt)) {
                continue;
            }
            String creatorId = entityExt.getCreatorId();
            handlerExplainDTO.setCreatorId(creatorId);
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(id, new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coopUserMap.getOrDefault(id, new ArrayList<>()));
            Boolean havePermission = ExplainUtil.advancedOperationHavePermission(mainUserField, handlerExplainDTO, FieldAdvanceOperationEnum.ADD.getOperation());
            String nameOrSerialNo = nameOrNoMap.get(id);
            if (!havePermission) {
                businessNameList.add(nameOrSerialNo);
                continue;
            }
            boolean userExist = false;
            for (String userId : userIdList) {
                if (teamUserList.contains(id + "_" + userId)){
                    failAddNameList.add(nameOrSerialNo);
                    userExist = true;
                    break;
                }
            }
            if (userExist) {
                continue;
            }
            List<String> addMainUsers = new ArrayList<>();
            for (String userId : userIdList){
                UserEntity userEntity = userEntityMap.get(userId);
                if (Objects.isNull(userEntity)) {
                    continue;
                }
                String key = id+"_"+userId;
                if ( userTeamEntityMap.containsKey(key) &&Objects.equals(userEntity.getDel(),DelEnum.DELETE.getDel()) ){
                    delBatchList.add(userTeamEntityMap.get(key));
                    continue;
                }
                if (!teamUserList.contains(key)){
                    addMainUsers.add(userEntity.getUserId());
                    UserTeamEntity userTeamEntity = new UserTeamEntity();
                    userTeamEntity.setIsMain(isMain);
                    userTeamEntity.setCorpid(corpid);
                    userTeamEntity.setDataId(id);
                    userTeamEntity.setUserId(userId);
                    userTeamEntity.setUserName(userEntity.getName());
                    userTeamEntity.setUserAvatar(userEntity.getAvatar());
                    insertBatchList.add(userTeamEntity);

                    List<Long> idList = userIdAndIdsMap.get(userId);
                    if (Objects.isNull(idList)) {
                        idList = new ArrayList<>();
                    }
                    idList.add(id);
                    userIdAndIdsMap.put(userId, idList);

                    List<String> userIds = idAndUserIdsMap.get(id);
                    if (Objects.isNull(userIds)) {
                        userIds = new ArrayList<>();
                    }
                    userIds.add(userId);
                    idAndUserIdsMap.put(id, userIds);
                }
            }
        }
        originalIds.removeAll(idAndUserIdsMap.keySet());
        //removeDataLock(originalIds, corpid, redisPrefix);
        if (!idAndUserIdsMap.isEmpty()) {
            BatchAddUserDTO batchAddUserDTO = new BatchAddUserDTO();
            BeanUtil.copyProperties(addMainUserDTO, batchAddUserDTO);
            batchAddUserDTO.setAddUserTeamEntities(insertBatchList);
            batchAddUserDTO.setIsMain(isMain);
            batchAddUserDTO.setUserIdAndIdsMap(userIdAndIdsMap);
            batchAddUserDTO.setUserEntityMap(userEntityMap);
            batchAddUserDTO.setIdAndUserIdsMap(idAndUserIdsMap);
            batchAddUserDTO.setIdAndNameMap(nameOrNoMap);
            batchAddUserDTO.setMainBusinessEntity(entityMap);
            userTeamService.batchAddUserTeam(batchAddUserDTO);
            //removeDataLock(new ArrayList<>(idAndUserIdsMap.keySet()), corpid, redisPrefix);
            if ( CollectionsUtil.isNotEmpty(delBatchList) ) {
                BatchDelUserDTO batchDelUserDTO = new BatchDelUserDTO();
                BeanUtil.copyProperties(addMainUserDTO, batchDelUserDTO);
                batchDelUserDTO.setDelUserTeamEntities(delBatchList);
                batchDelUserDTO.setIsMain(isMain);
                batchDelUserDTO.setUserEntityMap(userEntityMap);
                batchDelUserDTO.setIdAndUserIdsMap(idAndUserIdsMap);
                batchDelUserDTO.setUserIdAndIdsMap(userIdAndIdsMap);
                batchDelUserDTO.setIdAndNameMap(nameOrNoMap);
                userTeamService.batchDelUserTeam(batchDelUserDTO, WriteRequest.RefreshPolicy.NONE);
            }
            // 异步处理回款单或付款单的团队
            updateSheetTeam(corpid, businessType, idAndUserIdsMap.keySet());


            //api回调(添加负责人)
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
            switch (xbbRefTypeEnum) {
                case CUSTOMER_MANAGEMENT:
                case CUSTOMER:
                case SALES_OPPORTUNITY:
                case CONTRACT:
                    apiCallbackHelper.callbackBatch4Special(corpid, SaasMarkEnum.SAAS, new ArrayList<>(idAndUserIdsMap.keySet()), OperateTypeEnum.EDIT, xbbRefTypeEnum);
                default:
                    break;
            }
        }
        if (CollectionsUtil.isNotEmpty(businessNameList)) {
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.FAIL_REASON) + ErrorCodeEnum.API_ERROR_390007.getMsg());
            commonHelp.mergeFailMsg(businessNameList, dataIdSize, teamBatchPojo, I18nMessageUtil.getMessage(ListBatchConstant.ADD_MAIN_USER), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }
        if (!failAddNameList.isEmpty()) {
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.FAIL_REASON) + ErrorCodeEnum.API_ERROR_390009.getMsg());
            commonHelp.mergeFailMsg(failAddNameList, dataIdSize, teamBatchPojo, I18nMessageUtil.getMessage(ListBatchConstant.ADD_MAIN_USER), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }
        if (!lackIdList.isEmpty()){
            List<String> lackName = new ArrayList<>(lackIdList.size());
            for (Long id : lackIdList) {
                lackName.add(nameOrNoMap.getOrDefault(id, ""));
            }
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.USED_BY_OTHER));
            commonHelp.mergeFailMsg(lackName, dataIdSize, teamBatchPojo, I18nMessageUtil.getMessage(ListBatchConstant.ADD_MAIN_USER), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }
        if (teamBatchPojos.size() > 0) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
        }

        return teamBatchVO;*/

    }

    /**
     * 添加负责人动态日志
     * @param addMainUserDTO
     */
    private void checkJoinTeam(AddMainUserDTO addMainUserDTO){
        if (!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), addMainUserDTO.getDistributorMark())) {
            MainBusinessDynamicStrategy dynamicStrategy = dynamicStrategyFactory.getMainBusinessDynamicStrategyByBusinessType(addMainUserDTO.getBusinessType());
            dynamicStrategy.checkJoinTeam(new DynamicCheckJoinTeamDTO(addMainUserDTO));
        }
    }

    @Override
    public TeamBatchVO delMainUser(DelMainUserDTO delMainUserDTO) throws XbbException {
        TeamBatchVO teamBatchVO = new TeamBatchVO();

        int size = delMainUserDTO.getDataIdList().size();
        if (size > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }

        String corpid = delMainUserDTO.getCorpid();
        List<Long> dataIdList = delMainUserDTO.getDataIdList();
        Integer businessType = delMainUserDTO.getBusinessType();
        Long formId = delMainUserDTO.getFormId();
        UserVO loginUser = delMainUserDTO.getLoginUser();
        //数据权限校验
        List<TeamBatchPojo> teamBatchPojos = checkDataPermission4Share(dataIdList, businessType, formId, delMainUserDTO.getSaasMark(), corpid, loginUser, UserTeamOperateTagEnum.DEL_MAIN);


        // 批量的数据锁
        String redisPrefix = teamDataHelp.getRedisPrefix(delMainUserDTO.getSaasMark(), delMainUserDTO.getBusinessType());
        List<Long> lackIdList = dataLocking(delMainUserDTO.getDataIdList(), delMainUserDTO.getCorpid(), redisPrefix);

        List<TeamBatchPojo> batchPojo4Approval = teamHelp.checkDataIsApproval(delMainUserDTO.getDataIdList(), delMainUserDTO.getCorpid(), delMainUserDTO.getFormId(), delMainUserDTO.getSaasMark(), delMainUserDTO.getBusinessType(), UserTeamOperateTagEnum.DEL_MAIN);
        if(CollectionsUtil.isNotEmpty(batchPojo4Approval)){
            teamBatchPojos.addAll(batchPojo4Approval);
        }
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(delMainUserDTO, teamVerifyDTO);
        teamVerifyDTO.setDataId(delMainUserDTO.getDataIdList());
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setNewDelMainUserList(new HashSet<>(delMainUserDTO.getUserIdList()));
        teamVerifyDTO.setBatchTag(Constant.ONE);
        teamVerifyDTO.setLoginUser(delMainUserDTO.getLoginUser());

        teamBatchPojos.addAll(teamDataHelp.save(teamVerifyDTO));

        if (CollectionsUtil.isNotEmpty(lackIdList)){
            Map<Long, String> nameOrSeriNoMap = new HashMap<>();
            userTeamHelp.getEntityMap(teamVerifyDTO.getBusinessType(), lackIdList, teamVerifyDTO.getCorpid(), nameOrSeriNoMap, teamVerifyDTO.getSaasMark());
            List<String> lackName = new ArrayList<>(lackIdList.size());
            for (Long id : lackIdList) {
                lackName.add(nameOrSeriNoMap.getOrDefault(id, ""));
            }
            commonHelp.batchSameErrorPackage(lackName, UserTeamOperateTagEnum.DEL_MAIN.getName(),
                    UserTeamErrorCodeEnum.API_ERROR_271020.getCode(), UserTeamErrorCodeEnum.API_ERROR_271020.getMsg(), teamBatchPojos);
        }

        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
            commonHelp.batchFailMsg(teamBatchPojos, size, teamBatchVO);
        }
        return teamBatchVO;
    }

    @Override
    public TeamBatchVO addCoUser(AddCoUserDTO addCoUserDTO) throws XbbException{
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        int size = addCoUserDTO.getDataIdList().size();

        String corpid = addCoUserDTO.getCorpid();
        List<Long> dataIdList = addCoUserDTO.getDataIdList();
        Integer businessType = addCoUserDTO.getBusinessType();
        Long formId = addCoUserDTO.getFormId();
        UserVO loginUser = addCoUserDTO.getLoginUser();
        //数据权限校验
        List<TeamBatchPojo> teamBatchPojos = checkDataPermission4Share(dataIdList, businessType, formId, addCoUserDTO.getSaasMark(), corpid, loginUser, UserTeamOperateTagEnum.ADD_COUSER);

        String redisPrefix = teamDataHelp.getRedisPrefix(addCoUserDTO.getSaasMark(), addCoUserDTO.getBusinessType());
        List<Long> lackIdList = dataLocking(addCoUserDTO.getDataIdList(), addCoUserDTO.getCorpid(), redisPrefix);

        List<TeamBatchPojo> batchPojo4Approval = teamHelp.checkDataIsApproval(addCoUserDTO.getDataIdList(), addCoUserDTO.getCorpid(), addCoUserDTO.getFormId(), addCoUserDTO.getSaasMark(), addCoUserDTO.getBusinessType(), UserTeamOperateTagEnum.ADD_COUSER);
        if(CollectionsUtil.isNotEmpty(batchPojo4Approval)){
            teamBatchPojos.addAll(batchPojo4Approval);
        }
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(addCoUserDTO, teamVerifyDTO);
        teamVerifyDTO.setDataId(addCoUserDTO.getDataIdList());
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setNewAddCoUserList(new HashSet<>(addCoUserDTO.getUserIdList()));
        teamVerifyDTO.setBatchTag(Constant.ONE);
        teamVerifyDTO.setLoginUser(addCoUserDTO.getLoginUser());

        teamBatchPojos.addAll(teamDataHelp.save(teamVerifyDTO));

        if (CollectionsUtil.isNotEmpty(lackIdList)) {
            Map<Long, String> nameOrSeriNoMap = new HashMap<>();
            userTeamHelp.getEntityMap(teamVerifyDTO.getBusinessType(), lackIdList, teamVerifyDTO.getCorpid(), nameOrSeriNoMap, teamVerifyDTO.getSaasMark());
            List<String> lackName = new ArrayList<>(lackIdList.size());
            for (Long id : lackIdList) {
                lackName.add(nameOrSeriNoMap.getOrDefault(id, ""));
            }
            commonHelp.batchSameErrorPackage(lackName, UserTeamOperateTagEnum.ADD_COUSER.getName(),
                    UserTeamErrorCodeEnum.API_ERROR_271020.getCode(), UserTeamErrorCodeEnum.API_ERROR_271020.getMsg(), teamBatchPojos);
        }

        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
            commonHelp.batchFailMsg(teamBatchPojos, size, teamBatchVO);
        }
        return teamBatchVO;
    }

    /**
     * 共享模式校验团队数据权限
     *
     * @param dataIdList
     * @param businessType
     * @param formId
     * @param corpid
     * @param loginUser
     * @param userTeamOperateTagEnum
     * @return
     * @throws XbbException
     */
    private List<TeamBatchPojo> checkDataPermission4Share(List<Long> dataIdList, Integer businessType, Long formId, Integer saasMark, String corpid, UserVO loginUser, UserTeamOperateTagEnum userTeamOperateTagEnum) throws XbbException {
        List<TeamBatchPojo> teamBatchPojos =  new ArrayList<>();
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = formDataHelp.getByDataIdList(dataIdList, businessType, saasMark, formId, corpid);
        Map<Long, String> nameMap = userTeamHelp.getNameMap(paasFormDataEntityExtList, businessType);
        List<Long> errorDataIdList = new ArrayList<>();
        List<String> fileNames = new ArrayList<>();
        Map<Long, List<String>> ownerIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        businessUserTeamHelp.getUserIdMapSetShow(new HashSet<>(), dataIdList, corpid, businessType, false, ownerIdMap, coUserIdMap, DelEnum.NORMAL.getDel());
        //数据库获取相关规则
        List<ShareRuleEntity> ruleEntities = sharePermissionHelp.getRuleEntities(corpid, formId, loginUser.getUserId());
        //获取团队
        List<UserTeamEntity> userTeamList = userTeamHelp.getUserTeamList(dataIdList, corpid, businessType, false, null);
        Map<Long, List<UserTeamEntity>> userTeamMap = userTeamList.stream().collect(Collectors.toMap(UserTeamEntity::getDataId, Collections::singletonList, (v1, v2) -> {
            List<UserTeamEntity> result = new ArrayList<>();
            result.addAll(v1);
            result.addAll(v2);
            return result;
        }));
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
            paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
            paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
            VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
            boolean hasDataPermission = commonPermissionHelp.checkPermission(verifyUpdatePermissionDTO);
            if(hasDataPermission){
                //如果不是超管boss最大权限者 可能是没编辑权的协同人
                if (!loginUser.isMaxDataPermission() && !loginUser.isAdminOrBoss()){
                    Map<String, UserTeamEntity> collect = userTeamMap.get(paasFormDataEntityExt.getId()).stream().collect(Collectors.toMap(UserTeamEntity::getUserId, v -> v));
                    UserTeamEntity userTeamEntity = collect.get(loginUser.getUserId());
                    if(Objects.nonNull(userTeamEntity)){
                        if(Objects.equals(userTeamEntity.getIsMain(), Constant.ZERO) && Objects.equals(userTeamEntity.getFormPermission(), Constant.ZERO)){
                            //协同人只读，则没权限
                            hasDataPermission = false;
                        }
                    }
                }
            }
            if(!hasDataPermission){
                verifyUpdatePermissionDTO.setRuleEntities(ruleEntities);
                hasDataPermission = sharePermissionHelp.verifySharePermission4EditWithRuleEngine(verifyUpdatePermissionDTO);
            }
            if (!hasDataPermission){
                errorDataIdList.add(paasFormDataEntityExt.getId());
                fileNames.add(nameMap.get(paasFormDataEntityExt.getId()));
            }
        }
        if(CollectionUtils.isNotEmpty(errorDataIdList)){
            dataIdList.removeIf(errorDataIdList :: contains);
        }
        if(CollectionsUtil.isNotEmpty(errorDataIdList)){
            for (Long dataId : errorDataIdList) {
                String errorName =  nameMap.get(dataId);
                TeamBatchPojo teamBatchPojo = new TeamBatchPojo(SharePermissionErrorCodeEnum.API_ERROR_345005.getCode(), I18nMessageUtil.getMessage(ListBatchConstant.NO_OPERATE_PERMISSION),
                        errorName, userTeamOperateTagEnum.getName(),dataId);
                teamBatchPojos.add(teamBatchPojo);
            }
        }
        return teamBatchPojos;
    }


    /**
     * 隔离模式校验数据权限
     *
     * @param dataIdList
     * @param businessType
     * @param formId
     * @param corpid
     * @param loginUser
     * @param userTeamOperateTagEnum
     * @return
     * @throws XbbException
     */
    private List<TeamBatchPojo> checkDataPermission4Isolation(List<Long> dataIdList, Integer businessType, Long formId, String corpid, UserVO loginUser, UserTeamOperateTagEnum userTeamOperateTagEnum) throws XbbException {
        List<TeamBatchPojo> teamBatchPojos =  new ArrayList<>();
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = formDataHelp.getByDataIdList(dataIdList, businessType, SaasMarkEnum.SAAS.getCode(), formId, corpid);
        Map<Long, String> nameMap = userTeamHelp.getNameMap(paasFormDataEntityExtList, businessType);
        //判断操作人是否有全量数据权限
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(loginUser, userEntity);
        Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, businessType, 0L);
        Boolean hasMaxPermission = loginUser.isAdminOrBoss() || Objects.equals(DataPermissionEnum.ALL.getCode(), dataPermission);
        if(hasMaxPermission){
            return teamBatchPojos;
        }else{
            //创建团队和解散团队只有超管老板最大数据权限的人才行
            if(Objects.equals(userTeamOperateTagEnum, UserTeamOperateTagEnum.ADD_TEAM_TAG) || Objects.equals(userTeamOperateTagEnum, UserTeamOperateTagEnum.DEL_TEAM_TAG) ){
                for (Long dataId : dataIdList) {
                    String errorName =  nameMap.get(dataId);
                    TeamBatchPojo teamBatchPojo = new TeamBatchPojo(SharePermissionErrorCodeEnum.API_ERROR_345005.getCode(), I18nMessageUtil.getMessage(ListBatchConstant.NO_OPERATE_PERMISSION),
                            errorName, userTeamOperateTagEnum.getName(),dataId);
                    teamBatchPojos.add(teamBatchPojo);
                }
                dataIdList.clear();
                return teamBatchPojos;
            }
        }


        //判断操作人是否有某数据的团队成员的数据权限
        //批量查出所有团队数据
        List<UserTeamEntity> userTeamList = userTeamHelp.getUserTeamList(dataIdList, corpid, businessType, false, null);
        Map<Long, List<UserTeamEntity>> userTeamMap = userTeamList.stream().collect(Collectors.toMap(UserTeamEntity :: getDataId, Collections :: singletonList, (v1, v2) -> {
            List<UserTeamEntity> result = new ArrayList();
            result.addAll(v1);
            result.addAll(v2);
            return result;
        }));
        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, loginUser.getUserId(), loginUser.getCorpid(), BasicConstant.ZERO,false);
        Iterator<Long> iterator = dataIdList.iterator();
        while (iterator.hasNext()){
            Long dataId = iterator.next();
            List<String> userList = userTeamMap.get(dataId).stream().map(UserTeamEntity :: getUserId).collect(Collectors.toList());
            boolean hasTeamDataPer =  CollectionUtils.intersection(userList, userIdIn).size() > 0;
            if(!hasTeamDataPer){
                //从共享权限来的，不让操作
                iterator.remove();
                String errorName =  nameMap.get(dataId);
                TeamBatchPojo teamBatchPojo = new TeamBatchPojo(SharePermissionErrorCodeEnum.API_ERROR_345005.getCode(), I18nMessageUtil.getMessage(ListBatchConstant.NO_OPERATE_PERMISSION),
                        errorName, userTeamOperateTagEnum.getName(),dataId);
                teamBatchPojos.add(teamBatchPojo);
            }else{
                //团队过来的，如果是团队内协同人，则需要判断编辑权
                Map<String, UserTeamEntity> collect = userTeamMap.get(dataId).stream().collect(Collectors.toMap(UserTeamEntity::getUserId, v -> v));
                UserTeamEntity userTeamEntity = collect.get(loginUser.getUserId());
                if(Objects.nonNull(userTeamEntity)){
                    if(Objects.equals(userTeamEntity.getIsMain(), Constant.ZERO) && Objects.equals(userTeamEntity.getFormPermission(), Constant.ZERO)){
                        //协同人只读，则没权限
                        iterator.remove();
                        String errorName =  nameMap.get(dataId);
                        TeamBatchPojo teamBatchPojo = new TeamBatchPojo(SharePermissionErrorCodeEnum.API_ERROR_345005.getCode(), I18nMessageUtil.getMessage(ListBatchConstant.NO_OPERATE_PERMISSION),
                                errorName, userTeamOperateTagEnum.getName(),dataId);
                        teamBatchPojos.add(teamBatchPojo);
                    }
                }
            }
        }
        return teamBatchPojos;
    }

    @Override
    public TeamBatchVO delCoUser(DelCoUserDTO delCoUserDTO) throws XbbException {
        TeamBatchVO teamBatchVO = new TeamBatchVO();

        int size = delCoUserDTO.getDataIdList().size();

        String corpid = delCoUserDTO.getCorpid();
        List<Long> dataIdList = delCoUserDTO.getDataIdList();
        Integer businessType = delCoUserDTO.getBusinessType();
        Long formId = delCoUserDTO.getFormId();
        UserVO loginUser = delCoUserDTO.getLoginUser();
        //数据权限校验
        List<TeamBatchPojo> teamBatchPojos = checkDataPermission4Share(dataIdList, businessType, formId, delCoUserDTO.getSaasMark(), corpid, loginUser, UserTeamOperateTagEnum.DEL_COUSER);

        String redisPrefix = teamDataHelp.getRedisPrefix(delCoUserDTO.getSaasMark(), delCoUserDTO.getBusinessType());
        List<Long> lackIdList = dataLocking(delCoUserDTO.getDataIdList(), delCoUserDTO.getCorpid(), redisPrefix);

        List<TeamBatchPojo> batchPojo4Approval = teamHelp.checkDataIsApproval(delCoUserDTO.getDataIdList(), delCoUserDTO.getCorpid(), delCoUserDTO.getFormId(), delCoUserDTO.getSaasMark(), delCoUserDTO.getBusinessType(), UserTeamOperateTagEnum.DEL_COUSER);
        if(CollectionsUtil.isNotEmpty(batchPojo4Approval)){
            teamBatchPojos.addAll(batchPojo4Approval);
        }
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(delCoUserDTO, teamVerifyDTO);
        teamVerifyDTO.setDataId(delCoUserDTO.getDataIdList());
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setNewDelCoUserList(new HashSet<>(delCoUserDTO.getUserIdList()));
        teamVerifyDTO.setBatchTag(Constant.ONE);
        teamVerifyDTO.setLoginUser(delCoUserDTO.getLoginUser());

        teamBatchPojos.addAll(teamDataHelp.save(teamVerifyDTO));

        if (CollectionsUtil.isNotEmpty(lackIdList)){
            Map<Long, String> nameOrSeriNoMap = new HashMap<>();
            userTeamHelp.getEntityMap(teamVerifyDTO.getBusinessType(), lackIdList, teamVerifyDTO.getCorpid(), nameOrSeriNoMap, teamVerifyDTO.getSaasMark());
            List<String> lackName = new ArrayList<>(lackIdList.size());
            for (Long id : lackIdList) {
                lackName.add(nameOrSeriNoMap.getOrDefault(id, ""));
            }
            commonHelp.batchSameErrorPackage(lackName, UserTeamOperateTagEnum.DEL_COUSER.getName(),
                    UserTeamErrorCodeEnum.API_ERROR_271020.getCode(), UserTeamErrorCodeEnum.API_ERROR_271020.getMsg(), teamBatchPojos);
        }

        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
            commonHelp.batchFailMsg(teamBatchPojos, size, teamBatchVO);
        }
        return teamBatchVO;

    }

    @Override
    public TeamBatchVO portionUser(PortionUserDTO portionUserDTO) throws XbbException {
        if (portionUserDTO.getDataIdList().size() > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        List<Long> productIdList = portionUserDTO.getDataIdList();
        String corpid = portionUserDTO.getCorpid();
        StringBuilder productNameBuild = portionProductName(corpid,productIdList);
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",portionUserDTO.getCorpid());
        map.put("productIdIn",productIdList);
        map.put("type",0);
        map.put("del",0);
        List<ProductUserEntity> productUserEntityList = productUserModel.findEntitys(map);
        List<String> userIdList = portionUserDTO.getUserIdList();
//        List<Long> delIdList = new ArrayList<>();
        Map<Long,List<String>> hasUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ProductUserEntity entity : productUserEntityList){
//            if (!userIdList.contains(entity.getRelationId())){
//                delIdList.add(entity.getId());
//                continue;
//            }
            List<String> userList = hasUserMap.getOrDefault(entity.getDataId(),new ArrayList<>());
            userList.add(entity.getRelationId());
            hasUserMap.put(entity.getDataId(),userList);
        }
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery(ProductEnum.getEsAttr4Keyword(ProductEnum.PARENT_ID), productIdList));
        List<String> fieldList = Arrays.asList("id",ProductEnum.getAttrConnectData(ProductEnum.PARENT_ID));
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PRODUCT,boolQueryBuilder,PaasFormDataEntityExt.class, fieldList);

        List<ProductUserEntity> insetBatchList = new ArrayList<>();
        //父产品
        for (Long productId : productIdList){
            for (String userId : userIdList){
                if (hasUserMap.getOrDefault(productId,new ArrayList<>()).contains(userId)){
                    continue;
                }
                ProductUserEntity productUserEntity = new ProductUserEntity();
                productUserEntity.setCorpid(corpid);
                productUserEntity.setDataId(productId);
                productUserEntity.setParentId(0L);
                productUserEntity.setType(0);
                productUserEntity.setRelationId(userId);
                insetBatchList.add(productUserEntity);
            }
        }
        //子产品
        for (PaasFormDataEntityExt entity : paasFormDataEntityExtList){
            for (String userId : userIdList){
                Long productId = entity.getData().getLong(ProductEnum.PARENT_ID.getAttr());
                if (hasUserMap.getOrDefault(productId,new ArrayList<>()).contains(userId)){
                    continue;
                }
                ProductUserEntity productUserEntity = new ProductUserEntity();
                productUserEntity.setCorpid(corpid);
                productUserEntity.setDataId(entity.getId());
                productUserEntity.setParentId(productId);
                productUserEntity.setType(0);
                productUserEntity.setRelationId(userId);
                insetBatchList.add(productUserEntity);
            }
        }
//        //批量删除
//        if (!delIdList.isEmpty()){
//            productUserModel.deleteBatch(corpid,delIdList);
//        }
        //批量插入
        if (!insetBatchList.isEmpty()){
            productUserModel.inserBatch(insetBatchList);
        }
        return teamBatchVO;
    }


    @Override
    public TeamBatchVO portionRemoveUser(PortionMoveUserDTO portionMoveUserDTO) throws XbbException {
        if (portionMoveUserDTO.getDataIdList().size() > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        List<Long> productIdList = portionMoveUserDTO.getDataIdList();
        String corpid = portionMoveUserDTO.getCorpid();
        List<String> userIds = portionMoveUserDTO.getUserIdList();
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",portionMoveUserDTO.getCorpid());
        map.put("productIdIn",productIdList);
        map.put("relationIdIn",userIds);
        map.put("type",0);
        map.put("del",0);
        map.put(ParameterConstant.COLUMNS, "id,data_id");
        List<ProductUserEntity> productUserEntityList = productUserModel.findEntitys(map);
        if (productUserEntityList.isEmpty()) {
            teamBatchVO.setResultType(ListBatchResultEnum.OPERATE_SUCCESS.getAlias());
            teamBatchVO.setResultMsg(ListBatchResultEnum.OPERATE_SUCCESS.getMsg());
            return teamBatchVO;
        }
        List<Long> delIdList = new ArrayList<>();
        List<ProductUserEntity> delUserEntity = new ArrayList<>();
        for (ProductUserEntity entity : productUserEntityList){
            delIdList.add(entity.getId());
            delUserEntity.add(entity);
        }

        // 查询子产品团队
        Map<String,Object> subMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        subMap.put("corpid",portionMoveUserDTO.getCorpid());
        subMap.put("parentIdIn",productIdList);
        subMap.put("relationIdIn",userIds);
        subMap.put("type",0);
        subMap.put("del",0);
        map.put(ParameterConstant.COLUMNS, "id,data_id");
        List<ProductUserEntity> subProductUsers = productUserModel.findEntitys(subMap);
        for (ProductUserEntity entity : subProductUsers){
            delIdList.add(entity.getId());
            delUserEntity.add(entity);
        }
        //批量删除
        if (!delIdList.isEmpty()){
            productUserModel.batchDel(corpid, delIdList, delUserEntity);
        }
        return teamBatchVO;
    }


    @Override
    public TeamBatchVO portionRemoveDep(PortionMoveDepDTO portionMoveDepDTO) throws XbbException {
        if (portionMoveDepDTO.getDataIdList().size() > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        List<Long> depIdList = portionMoveDepDTO.getDepIdList();
        List<String> depIdStrList = new ArrayList<>();
        depIdList.forEach(item -> {
            String depIdStr = item.toString();
            depIdStrList.add(depIdStr);
        });
        String corpid = portionMoveDepDTO.getCorpid();
        List<Long> productIdList = portionMoveDepDTO.getDataIdList();
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid", corpid);
        map.put("productIdIn", productIdList);
        map.put("relationIdIn", depIdStrList);
        map.put("type", 1);
        map.put("del", 0);
        map.put(ParameterConstant.COLUMNS, "id,data_id");
        List<ProductUserEntity> productUserEntityList = productUserModel.findEntitys(map);
        if (productUserEntityList.isEmpty()) {
            teamBatchVO.setResultType(ListBatchResultEnum.OPERATE_SUCCESS.getAlias());
            teamBatchVO.setResultMsg(ListBatchResultEnum.OPERATE_SUCCESS.getMsg());
            return teamBatchVO;
        }
        List<Long> delIdList = new ArrayList<>();
        List<ProductUserEntity> delUserEntity = new ArrayList<>();
        for (ProductUserEntity entity : productUserEntityList){
            delIdList.add(entity.getId());
            delUserEntity.add(entity);
        }

        // 查询子产品团队
        Map<String,Object> subMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        subMap.put("corpid", corpid);
        subMap.put("parentIdIn", productIdList);
        subMap.put("relationIdIn", depIdStrList);
        subMap.put("type", 1);
        subMap.put("del", 0);
        map.put(ParameterConstant.COLUMNS, "id,data_id");
        List<ProductUserEntity> subProductUsers = productUserModel.findEntitys(subMap);

        for (ProductUserEntity entity : subProductUsers){
            delIdList.add(entity.getId());
            delUserEntity.add(entity);
        }

        //批量删除
        if (!delIdList.isEmpty()){
            productUserModel.batchDel(corpid, delIdList, delUserEntity);
        }
        return teamBatchVO;
    }

    @Override
    public TeamBatchVO portionDep(PortionDepDTO portionDepDTO) throws XbbException {
        if (portionDepDTO.getDataIdList().size() > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        List<Long> productIdList = portionDepDTO.getDataIdList();
        String corpid = portionDepDTO.getCorpid();
        StringBuilder productNameBuild = portionProductName(corpid,productIdList);
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",corpid);
        map.put("productIdIn",productIdList);
        map.put("type",1);
        map.put("del",0);
        List<ProductUserEntity> productUserEntityList = productUserModel.findEntitys(map);
        List<Long> depIdList = portionDepDTO.getDepIdList();
//        List<Long> delIdList = new ArrayList<>();
        Map<Long,List<String>> hasUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ProductUserEntity entity : productUserEntityList){
//            if (!depIdList.contains(Long.valueOf(entity.getRelationId()))){
//                delIdList.add(entity.getId());
//                continue;
//            }
            List<String> depList = hasUserMap.getOrDefault(entity.getDataId(),new ArrayList<>());
            depList.add(entity.getRelationId());
            hasUserMap.put(entity.getDataId(),depList);
        }
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery(ProductEnum.getEsAttr4Keyword(ProductEnum.PARENT_ID), productIdList));
        List<String> fieldList = Arrays.asList("id",ProductEnum.getAttrConnectData(ProductEnum.PARENT_ID));
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PRODUCT,boolQueryBuilder,PaasFormDataEntityExt.class, fieldList);


        List<ProductUserEntity> insetBatchList = new ArrayList<>();
        for (Long productId : productIdList){
            for (Long depId : depIdList){
                if (hasUserMap.getOrDefault(productId,new ArrayList<>()).contains(depId.toString())){
                    continue;
                }
                ProductUserEntity productUserEntity = new ProductUserEntity();
                productUserEntity.setCorpid(corpid);
                productUserEntity.setDataId(productId);
                productUserEntity.setParentId(0L);
                productUserEntity.setType(1);
                productUserEntity.setRelationId(depId.toString());
                insetBatchList.add(productUserEntity);
            }
        }
        for (PaasFormDataEntityExt entity : paasFormDataEntityExtList){
            for (Long depId : depIdList){
                Long productId = entity.getData().getLong(ProductEnum.PARENT_ID.getAttr());
                if (hasUserMap.getOrDefault(productId,new ArrayList<>()).contains(depId.toString())){
                    continue;
                }
                ProductUserEntity productUserEntity = new ProductUserEntity();
                productUserEntity.setCorpid(corpid);
                productUserEntity.setDataId(entity.getId());
                productUserEntity.setParentId(productId);
                productUserEntity.setType(1);
                productUserEntity.setRelationId(depId.toString());
                insetBatchList.add(productUserEntity);
            }
        }
//        //批量删除
//        if (!delIdList.isEmpty()) {
//            productUserModel.deleteBatch(corpid,delIdList);
//        }
        //批量插入
        if (!insetBatchList.isEmpty()) {
            productUserModel.inserBatch(insetBatchList);
        }
        return teamBatchVO;
    }


    @Override
    public TeamBatchVO portionCompetitorUser(PortionCompetitorUserDTO portionUserDTO) throws XbbException {
        String corpid = portionUserDTO.getCorpid();
        List<Long> dataIdList = portionUserDTO.getDataIdList();
        List<String> userIdList = portionUserDTO.getUserIdList();
        if (dataIdList.size() > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }
        //批量分配竞争对手可见人
        TeamBatchVO teamBatchVO = portionUserOrDep(corpid, dataIdList, userIdList, 0);

        // 日志保存
        afterPortionVisibleLog(corpid,portionUserDTO.getUserId(),portionUserDTO.getLoginUserName(),portionUserDTO.getHttpHeader(),dataIdList,userIdList,true);
        return teamBatchVO;
    }

    private void afterPortionVisibleLog(String corpid,String userId,String userName,String httpHeader,List<Long> dataIdList,List<String> relationIdList,boolean isUser){
        CompetitorPortionVisibleLogDTO logDTO = new CompetitorPortionVisibleLogDTO();
        logDTO.setCorpid(corpid);
        logDTO.setUserId(userId);
        logDTO.setLoginUserName(userName);
        logDTO.setDataIdList(dataIdList);
        logDTO.setRelationIdList(relationIdList);
        logDTO.setHttpHeader(httpHeader);

        CompetitorOperationLogHandle competitorOperationLogHandle = (CompetitorOperationLogHandle) operationLogFactory.getOperationLogHandle(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.COMPETITOR.getCode());
        if (Objects.nonNull(competitorOperationLogHandle)) {
            if (isUser){
                competitorOperationLogHandle.portionCompetitorUser(logDTO);
            }else {
                competitorOperationLogHandle.portionCompetitorDep(logDTO);
            }
        }
    }

    private void afterRemoveVisibleLog(String corpid,String userId,String userName,String httpHeader,List<Long> dataIdList,List<String> relationIdList,boolean isUser){
        CompetitorRemoveVisibleLogDTO logDTO = new CompetitorRemoveVisibleLogDTO();
        logDTO.setCorpid(corpid);
        logDTO.setUserId(userId);
        logDTO.setLoginUserName(userName);
        logDTO.setDataIdList(dataIdList);
        logDTO.setRelationIdList(relationIdList);
        logDTO.setHttpHeader(httpHeader);

        CompetitorOperationLogHandle competitorOperationLogHandle = (CompetitorOperationLogHandle) operationLogFactory.getOperationLogHandle(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.COMPETITOR.getCode());
        if (Objects.nonNull(competitorOperationLogHandle)) {
            if (isUser){
                competitorOperationLogHandle.removeCompetitorUser(logDTO);
            }else {
                competitorOperationLogHandle.removeCompetitorDep(logDTO);
            }
        }
    }

    @Override
    public BaseVO portionCompetitorDep(PortionCompetitorDepDTO portionDepDTO) throws XbbException {
        String corpid = portionDepDTO.getCorpid();
        List<Long> dataIdList = portionDepDTO.getDataIdList();
        //因为部门id是long类型，统一转化为字符串
        List<String> depIdList = portionDepDTO.getDepIdList().stream().map(item -> item.toString()).collect(Collectors.toList());
        if (dataIdList.size() > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }
        //批量分配竞争对手可见部门
        TeamBatchVO teamBatchVO = portionUserOrDep(corpid, dataIdList, depIdList, 1);

        // 日志保存
        afterPortionVisibleLog(corpid,portionDepDTO.getUserId(),portionDepDTO.getLoginUserName(),portionDepDTO.getHttpHeader(),dataIdList,depIdList,false);
        return teamBatchVO;
    }

    @Override
    public BaseVO portionRemoveCompetitorUser(PortionMoveCompetitorUserDTO portionMoveUserDTO) throws XbbException {
        String corpid = portionMoveUserDTO.getCorpid();
        List<Long> dataIdList = portionMoveUserDTO.getDataIdList();
        List<String> userIdList = portionMoveUserDTO.getUserIdList();

        if (dataIdList.size() > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }
        TeamBatchVO teamBatchVO = RemoveUserOrDep(corpid, dataIdList, userIdList, 0);
        // 日志保存
        afterRemoveVisibleLog(corpid,portionMoveUserDTO.getUserId(),portionMoveUserDTO.getLoginUserName(),portionMoveUserDTO.getHttpHeader(),dataIdList,userIdList,true);
        return teamBatchVO;
    }


    @Override
    public BaseVO portionRemoveCompetitorDep(PortionMoveCompetitorDepDTO portionMoveDepDTO) throws XbbException {
        String corpid = portionMoveDepDTO.getCorpid();
        List<Long> dataIdList = portionMoveDepDTO.getDataIdList();
        //部门id为long类型，需要转化为string类型
        List<String> depIdList = portionMoveDepDTO.getDepIdList().stream().map(item -> item.toString()).collect(Collectors.toList());
        if (dataIdList.size() > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }
        TeamBatchVO teamBatchVO = RemoveUserOrDep(corpid, dataIdList, depIdList, 1);
        //日志保存
        afterRemoveVisibleLog(corpid,portionMoveDepDTO.getUserId(),portionMoveDepDTO.getLoginUserName(),portionMoveDepDTO.getHttpHeader(),dataIdList,depIdList,false);
        return teamBatchVO;
    }

    /**
     * 批量分配竞争对手可见人或可见部门
     * @param corpid
     * @param dataIdList
     * @param relationIdList
     * @param isUserOrDep
     * @return
     * @throws XbbException
     */
    private TeamBatchVO portionUserOrDep(String corpid,List<Long> dataIdList,List<String> relationIdList,int isUserOrDep) throws XbbException {

        TeamBatchVO teamBatchVO = new TeamBatchVO();
        Map<String, Object> paramMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        paramMap.put("corpid",corpid);
        paramMap.put("competitorIdIn",dataIdList);
        paramMap.put("type",isUserOrDep);
        paramMap.put("del",0);
        List<CompetitorUserEntity> competitorUserModelEntitys = competitorUserModel.findEntitys(paramMap);

        Map<Long, List<String>> hasUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (CompetitorUserEntity entity : competitorUserModelEntitys) {
            List<String> relationList = hasUserMap.getOrDefault(entity.getDataId(), new ArrayList<>());
            relationList.add(entity.getRelationId());
            hasUserMap.put(entity.getDataId(),relationList);
        }

        List<CompetitorUserEntity> insertBatchList = new ArrayList<>();
        for (Long dataId : dataIdList) {
            for (String relationId: relationIdList){
                if (hasUserMap.getOrDefault(dataId,new ArrayList<>()).contains(relationId)){
                    continue;
                }
                CompetitorUserEntity entity = new CompetitorUserEntity();
                entity.setCorpid(corpid);
                entity.setDataId(dataId);
                entity.setType(isUserOrDep);
                entity.setRelationId(relationId);
                insertBatchList.add(entity);
            }
        }
        if (CollectionUtils.isNotEmpty(insertBatchList)){
            competitorUserModel.inserBatch(insertBatchList);
        }
        return teamBatchVO;
    }


    /**
     * 批量移除竞争对手可见人或者可见部门
     * @param corpid 公司id
     * @param dataIdList 竞争对手ID
     * @param relationsList 可见人或者可见部门id
     * @param isUserOrDep 0:可见人，1:可见部门
     * @return
     * @throws XbbException
     */
    private TeamBatchVO RemoveUserOrDep(String corpid,List<Long> dataIdList,List<String> relationsList,int isUserOrDep) throws XbbException{

        TeamBatchVO teamBatchVO = new TeamBatchVO();
        //封装查询条件
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID,corpid);
        params.put("competitorIdIn",dataIdList);
        params.put("relationIdIn",relationsList);
        params.put("type",isUserOrDep);
        params.put("del",DelEnum.NORMAL.getDel());
        params.put(ParameterConstant.COLUMNS,"id,data_id");
        List<CompetitorUserEntity> competitorUserModelEntityList = competitorUserModel.findEntitys(params);
        if (CollectionsUtil.isEmpty(competitorUserModelEntityList)){
            teamBatchVO.setResultType(ListBatchResultEnum.OPERATE_SUCCESS.getAlias());
            teamBatchVO.setResultMsg(ListBatchResultEnum.OPERATE_SUCCESS.getMsg());
            return teamBatchVO;
        }
        //获取需要删除的可见人id
        List<Long> readyDelIdList = competitorUserModelEntityList.stream().map(user -> user.getId()).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(readyDelIdList)) {
            competitorUserModel.deleteBatch(corpid,readyDelIdList,competitorUserModelEntityList);
        }
        return teamBatchVO;
    }

    @Override
    public BaseVO focus(FocusDTO focusDTO) throws XbbException {
        switch (XbbRefTypeEnum.getByCode(focusDTO.getBusinessType())){
            case CUSTOMER_MANAGEMENT:
                customerService.focus(focusDTO);
                break;
            case SALES_OPPORTUNITY:
                opportunityService.focus(focusDTO);
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        operationLogHelp.addOrDeleteFocus(focusDTO);
        return new BaseVO();
    }


    @Override
    public FormDataDeleteBatchVO deleteBatch(FormDataDeleteBatchDTO formDataDeleteBatchDTO) throws XbbException {
        //formDataDeleteBatchDTO.setSingleFlag(BasicConstant.ZERO);
        FormDataDeleteBatchVO formDataDeleteBatchVO = new FormDataDeleteBatchVO();
        Integer saasMark = formDataDeleteBatchDTO.getSaasMark();
        String userId = formDataDeleteBatchDTO.getUserId();
        String userName = formDataDeleteBatchDTO.getLoginUserName();
        String corpid = formDataDeleteBatchDTO.getCorpid();
        Long formId = formDataDeleteBatchDTO.getFormId();
        boolean isSkipPermissionCheck = Objects.equals(formDataDeleteBatchDTO.getIsSkipPermissionCheck(), BasicConstant.ONE);
        List<Long> dataIdList = formDataDeleteBatchDTO.getDataIdList();
        try {
            // 经销商业务改businessType
            Integer distributorMark = formDataDeleteBatchDTO.getDistributorMark();
            Integer businessType = formDataDeleteBatchDTO.getBusinessType();
            if (Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode())) {
                businessType = XbbRefTypeEnum.transferBusinessType4Distributor(businessType, distributorMark);
                formDataDeleteBatchDTO.setBusinessType(businessType);
            }
//            BusinessDeleteService businessDeleteService = businessDeleteMap.get(businessType);
//            if (Objects.nonNull(businessDeleteService)) {
//                return businessDeleteService.deleteBatch(formDataDeleteBatchDTO);
//            }
            VerifyDeletePermissionDTO verifyDeletePermissionDTO = new VerifyDeletePermissionDTO();
            BeanUtil.copyProperties(formDataDeleteBatchDTO, verifyDeletePermissionDTO);
            ProPermissionHelp.verifyDeletePermission(verifyDeletePermissionDTO);
            if (!Objects.equals(formDataDeleteBatchDTO.getIsBusinessRule(), 1) && Objects.equals(formDataDeleteBatchDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
               if (dataIdList.size() > 200) {
                   // 客户删除，最多200条
                   throw new XbbException(SystemErrorCodeEnum.API_ERROR_100079.getCode(), SystemErrorCodeEnum.API_ERROR_100079.getMsg(), 200);
               }
            } else {
                if (dataIdList.size() > 100) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100079.getCode(), SystemErrorCodeEnum.API_ERROR_100079.getMsg(), 100);
                }
            }
            Map<Long, List<String>> ownerIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, List<String>> coUserIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            businessUserTeamHelp.getUserIdMapSetShow(new HashSet<>(), dataIdList, corpid, businessType, false, ownerIdMap, coUserIdMap, DelEnum.NORMAL.getDel());
            UserVO loginUser = formDataDeleteBatchDTO.getLoginUser();
            if (isSkipPermissionCheck){
                //来自导入的不校验权限(场景:联合导入客户+联系人)
                //来自连接器的不校验权限(场景:系统与第三方平台的数据同步)
                //来自工作流的不校验权限(场景:工作流节点删除)
            }else if (Objects.equals(formDataDeleteBatchDTO.getSingleFlag(), BasicConstant.ONE)){
                PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormData(corpid, saasMark, businessType, dataIdList.get(0));
                if (Objects.isNull(paasFormDataEntityExt)){
                    return new FormDataDeleteBatchVO();
                }
                paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
                paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
                VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
                boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
                if (!hasDataPermission){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), OperateTypeEnum.DELETE.getName()));
                }
            }else{
                List<PaasFormDataEntityExt> paasFormDataEntityExtList = formDataHelp.getByDataIdList(dataIdList, formDataDeleteBatchDTO.getBusinessType(), formDataDeleteBatchDTO.getSaasMark(), formId, corpid);
                List<Long> errorDataIdList = new ArrayList<>();
                List<ShareRuleEntity> ruleEntities;
                if (Objects.equals(formDataDeleteBatchDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode()) && Objects.equals(formDataDeleteBatchDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                    // 老工单不支持共享权限
                    ruleEntities = new ArrayList<>();
                } else {
                    //数据库获取相关规则
                    ruleEntities = sharePermissionHelp.getRuleEntities(corpid, formId, loginUser.getUserId());
                }
                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
                    paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
                    paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
                    VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
                    verifyUpdatePermissionDTO.setRuleEntities(ruleEntities);
                    boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
                    if (!hasDataPermission){
                        errorDataIdList.add(paasFormDataEntityExt.getId());
                    }
                }
                if(CollectionUtils.isNotEmpty(errorDataIdList)){
                    dataIdList.removeIf(errorDataIdList :: contains);
                }
            }
            if(CollectionUtils.isEmpty(dataIdList)){
                return formDataDeleteBatchVO;
            }
            PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
            String businessRules;
            if (Objects.equals(formDataDeleteBatchDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())
                    && Objects.equals(formDataDeleteBatchDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                if (Objects.equals(formId, 0L)) {
                    // 如果该工单有已生成工单出库单时，不允许删除(批量时只要有一个有问题就返回错误)
                    OutStockListDTO outstockListDTO = new OutStockListDTO();
                    BeanUtil.copyProperties(formDataDeleteBatchDTO, outstockListDTO);
                    outstockListDTO.setRefIdIn(formDataDeleteBatchDTO.getDataIdList());
                    outstockListDTO.setType(OutstockTypeEnum.WORK_ORDER_OUTSTOCK.getCode());
                    OutStockListVO outstockListVO = outstockService.findOutstockList(outstockListDTO);
                    Set<String> nameList = new HashSet<>();
                    for (PaasFormDataEntityExt paasFormDataEntityExt : outstockListVO.getOutstockList()) {
                        String workName = FastJsonHelper.getStringFromFormData(paasFormDataEntityExt.getData(), OutstockEnum.REF_ID_LINKED_TEXT.getAttr());
                        nameList.add(workName);
                    }
                    String nameStr = Strings.join(nameList, StringConstant.COMMA);
                    if (!Objects.equals(outstockListVO.getOutstockList().size(), BasicConstant.ZERO)) {
                        throw new XbbException(WorkOrderErrorCodeEnum.API_ERROR_222070, String.format(WorkOrderErrorCodeEnum.API_ERROR_222070.getMsg(), nameStr));
                    }

                    // 全部工单列表，快速删除处理
                    List<Long> dataIds = formDataDeleteBatchDTO.getDataIdList();
                    if (dataIds != null && dataIds.size() < 1) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
                    }
                    WorkOrderEntity workOrderEntity = workOrderModel.getByKey(dataIds.get(0), corpid);
                    formId = workOrderEntity.getFormId();
                }
                WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(formId, corpid);
                if(Objects.isNull(workOrderFormEntityExt)){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }

                businessRules = workOrderFormEntityExt.getBusinessRules();
            } else {
                paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
                if(Objects.isNull(paasFormEntityExt)){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                businessRules = paasFormEntityExt.getBusinessRules();
            }

            List<PaasFormDataEntityExt> paasFormDataEntityExtList = null;
            PaasFormExplainEntity paasFormExplainEntity = null;
            List<FieldAttrEntity> explainList = null;
            Map<String, FieldAttrEntity> explainMap = null;
            if (SaasMarkEnum.SAAS.getCode().equals(formDataDeleteBatchDTO.getSaasMark())) {
//                formDataDeleteBatchDTO.setIsBatch(1);
                formDataDeleteBatchVO = saasDeleteHelp.deleteBatch(formDataDeleteBatchDTO);
            } else {
                // 没有saasMark标志的，现在全按paas应用来处理
                Map<String, Object> param = BeanUtil.convertBean2Map(formDataDeleteBatchDTO, true);
                param.put("ids", dataIdList);
                paasFormDataEntityExtList = paasFormDataModel.findEntitys(param);
                paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
                explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
                List<String> titleList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                for(PaasFormDataEntityExt entityExt : paasFormDataEntityExtList){
                    // 解析标题
                    PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt();
                    BeanUtil.copyProperties(entityExt, paasFormDataEntityExt);
                    List<FormTitlePoJo> formTitleList = ExplainUtil.getFormTitle(JSONArray.parseArray(paasFormEntityExt.getCustomTitle()), explainMap,
                            entityExt.getData(), explainList, paasFormDataEntityExt);
                    String title = "--";
                    if(!formTitleList.isEmpty()){
                        for (FormTitlePoJo titlePoJo : formTitleList) {
                            FieldAttrEntity fieldAttrEntity = explainMap.get(titlePoJo.getAttr());
                            if (Objects.isNull(fieldAttrEntity) || Objects.isNull(titlePoJo.getValue())) {
                                continue;
                            }
                            if (ExplainUtil.isCombo(fieldAttrEntity.getFieldType())) {
                                JSONObject jsonObject = new JSONObject();
                                jsonObject.put(titlePoJo.getAttr(), titlePoJo.getValue());
                                Object iteamValue = ItemUtil.analysisComboReturnStr(jsonObject, fieldAttrEntity);
                                String s = String.valueOf(iteamValue);
                                if(!StringUtil.isEmpty(s)) {
                                    titleList.add(s);
                                }
                            } else {
                                titleList.add(StringUtils.join(titlePoJo.getValue(), ""));
                            }
                        }
                    }
                    if(titleList.isEmpty()){
                        titleList.add(title);
                    }
                }

                paasFormDataModel.deleteBatch(dataIdList, corpid, DelEnum.DELETE.getDel());
                formDataDeleteBatchVO.setDeleteIds(dataIdList);
                // 业务规则逻辑 end
                OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
                if (Objects.equals(1, formDataDeleteBatchDTO.getIsBusinessRule())) {
                    operateTypeEnum = OperateTypeEnum.RULE_DELETE;
                }
                // paas记录日志(有名称的格式为编号(名称)，无名称的格式为编号)
                String logMemo = StringUtils.join(titleList, "，");
                if(dataIdList.size() > 1 ){
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, paasFormEntityExt.getName(), dataIdList.size());
                    List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    InfoArrPojo infoArrPojo = new InfoArrPojo();
                    infoArrPojo.setTitle(paasFormEntityExt.getName());
                    infoArrPojo.setContent(logMemo);
                    infoArrPojoList.add(infoArrPojo);
                    mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM_DATA, operateTypeEnum,
                            "", "", memo, formDataDeleteBatchDTO.getHttpHeader());
                } else if (Objects.equals(dataIdList.size(), 1)){
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, paasFormEntityExt.getName(), logMemo);
                    mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM_DATA, operateTypeEnum,
                            dataIdList.get(0).toString(), logMemo, memo, formDataDeleteBatchDTO.getHttpHeader());
                }
            }
            // 动态
            AnalysisDataDTO analysisDataDTO = new AnalysisDataDTO();
            BeanUtil.copyProperties(formDataDeleteBatchDTO,analysisDataDTO);
            dynamicHelp.deleteLinkData(corpid,saasMark,businessType,dataIdList,userId,userName,formId,paasFormDataEntityExtList,
                    explainMap,analysisDataDTO);

            List<Long> deleteIds = formDataDeleteBatchVO.getDeleteIds();
            // 低代码服务请求
            lowCodeExecuteService(deleteIds, formDataDeleteBatchDTO.getSaasMark(), formDataDeleteBatchDTO.getBusinessType(), formDataDeleteBatchDTO.getFormId(), corpid);
            List<Integer> returnDelete = Arrays.asList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(),
                    XbbRefTypeEnum.CONTRACT.getCode(), XbbRefTypeEnum.PAYMENT.getCode(), XbbRefTypeEnum.PAY_PLAN.getCode(),
                    XbbRefTypeEnum.PURCHASE.getCode(), XbbRefTypeEnum.SUPPLIER.getCode());
            if (!returnDelete.contains(formDataDeleteBatchDTO.getBusinessType())) {
                deleteIds = new ArrayList<>();
                deleteIds.addAll(dataIdList);
            }

            //是否启用新工作流
            if (isEnableNewWorkflow(formDataDeleteBatchDTO, formDataDeleteBatchVO, deleteIds, WorkflowOperateEnum.DELETE_BATCH)) {
                // 业务规则逻辑 start
                inactiveRule(formDataDeleteBatchDTO, businessRules, deleteIds);
                return formDataDeleteBatchVO;
            }

            // 业务规则逻辑 start
            inactiveRule(formDataDeleteBatchDTO, businessRules, deleteIds);
            // 富文本删除
            deleteRichText(formDataDeleteBatchDTO, deleteIds);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("listBatchServiceImpl.deleteBatch 执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formDataDeleteBatchVO;
    }

    /**
     * 是否启用新工作流
     * 且判断是否符合触发类型
     * @param formDataUpdateBatchDTO
     * @return
     * @throws XbbException
     */
    private boolean isEnableNewWorkflow(FormDataUpdateBatchDTO formDataUpdateBatchDTO, List<PaasFormDataEntityExt> oldDataList) throws XbbException {
        if (!commonHelp.isOpenWorkFlow(formDataUpdateBatchDTO.getCorpid())) {
            return false;
        }
        // 套餐限制
        Integer allStatus = packageStatusHelp.getPackageStatus(formDataUpdateBatchDTO.getCorpid(), ValueAddedTypeEnum.WORKFLOW, formDataUpdateBatchDTO.getDataIdList().size());
        if ( !Objects.equals(allStatus, PackageStatusEnum.NORMAL.getCode())) {
            return true;
        }
        //是不是要循环发送
        workflowFormDataOperationService.workflowUpdateBatchTrigger(formDataUpdateBatchDTO, oldDataList);
        return true;
    }

    /**
     * 是否启用新工作流
     * 且判断是否符合触发类型
     * @param formDataDeleteBatchDTO
     * @param formDataDeleteBatchVO
     * @return
     * @throws XbbException
     */
    private boolean isEnableNewWorkflow(FormDataDeleteBatchDTO formDataDeleteBatchDTO, FormDataDeleteBatchVO formDataDeleteBatchVO, List<Long> deleteIds, WorkflowOperateEnum workflowOperateEnum) throws XbbException {
        //是不是要循环发送
        return workflowFormDataOperationService.isEnableNewWorkflow(formDataDeleteBatchDTO, deleteIds, workflowOperateEnum);
    }

    @Override
    public FormDataDeleteBatchVO deleteBySingle(FormDataDeleteBatchDTO formDataDeleteBatchDTO) throws XbbException {
        formDataDeleteBatchDTO.setSingleFlag(BasicConstant.ONE);
        FormDataDeleteBatchVO formDataDeleteBatchVO = new FormDataDeleteBatchVO();
        Integer fromProcess = formDataDeleteBatchDTO.getFromProcess();
        UserVO loginUser = formDataDeleteBatchDTO.getLoginUser();
        String userId = formDataDeleteBatchDTO.getUserId();
        String userName = formDataDeleteBatchDTO.getLoginUserName();
        String corpid = formDataDeleteBatchDTO.getCorpid();
        Long formId = formDataDeleteBatchDTO.getFormId();
        List<Long> dataIdList = formDataDeleteBatchDTO.getDataIdList();
        Integer saasMark = formDataDeleteBatchDTO.getSaasMark();
        try {
            // 经销商业务改businessType
            Integer distributorMark = formDataDeleteBatchDTO.getDistributorMark();
            Integer businessType = formDataDeleteBatchDTO.getBusinessType();
            if (Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode())) {
                businessType = XbbRefTypeEnum.transferBusinessType4Distributor(businessType, distributorMark);
                formDataDeleteBatchDTO.setBusinessType(businessType);
            }
            // 审批不需要校验表单权限
            if (!Objects.equals(fromProcess, 1)) {
                VerifyDeletePermissionDTO verifyDeletePermissionDTO = new VerifyDeletePermissionDTO();
                BeanUtil.copyProperties(formDataDeleteBatchDTO, verifyDeletePermissionDTO);
                ProPermissionHelp.verifyDeletePermission(verifyDeletePermissionDTO);
                PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormDataWithTeam(corpid, saasMark, businessType, dataIdList.get(0));;
                VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
                boolean hasDataEditPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
                if (!hasDataEditPermission){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, SystemErrorCodeEnum.API_ERROR_100050.getMsg(), I18nMessageUtil.getMessage(CommonConstant.DEL));
                }
            }
            String businessRules;
            PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
            if (Objects.equals(formDataDeleteBatchDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode()) && Objects.equals(formDataDeleteBatchDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(formId, corpid);
                if (Objects.isNull(workOrderFormEntityExt)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                businessRules = workOrderFormEntityExt.getBusinessRules();
            } else {
                paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
                if(Objects.isNull(paasFormEntityExt)){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                businessRules = paasFormEntityExt.getBusinessRules();
            }

            List<PaasFormDataEntityExt> paasFormDataEntityExtList = null;
            PaasFormExplainEntity paasFormExplainEntity = null;
            List<FieldAttrEntity> explainList = null;
            Map<String, FieldAttrEntity> explainMap = null;
            if (SaasMarkEnum.SAAS.getCode().equals(formDataDeleteBatchDTO.getSaasMark())) {
                if (Objects.isNull(formDataDeleteBatchDTO.getBusinessType())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, SystemErrorCodeEnum.API_ERROR_100002.getMsg());
                }
                //转为单一
                formDataDeleteBatchVO = saasDeleteHelp.deleteBatch(formDataDeleteBatchDTO);
            } else {
                // 没有saasMark标志的，现在全按paas应用来处理
                Map<String, Object> param = BeanUtil.convertBean2Map(formDataDeleteBatchDTO, true);
                param.put("ids", dataIdList);
                paasFormDataEntityExtList = paasFormDataModel.findEntitys(param);
                paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
                explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
                List<String> titleList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                for(PaasFormDataEntityExt entityExt : paasFormDataEntityExtList){
                    // 解析标题
                    PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt();
                    BeanUtil.copyProperties(entityExt, paasFormDataEntityExt);
                    List<FormTitlePoJo> formTitleList = ExplainUtil.getFormTitle(JSONArray.parseArray(paasFormEntityExt.getCustomTitle()), explainMap,
                            entityExt.getData(), explainList, paasFormDataEntityExt);
                    String title = "--";
                    if(!formTitleList.isEmpty()){
                        List<Object> value = formTitleList.get(0).getValue();
                        title = value.isEmpty() ? title : value.get(0).toString();
                        titleList.add(title);
                    }
                }

                //转为单一
                paasFormDataModel.delete(dataIdList.get(0).intValue(), corpid);

                //paasFormDataModel.deleteBatch(formDataDeleteBatchDTO.getDataIdList(), formDataDeleteBatchDTO.getCorpid(), DelEnum.DELETE.getDel());
                OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
                if (Objects.equals(1, formDataDeleteBatchDTO.getIsBusinessRule())) {
                    operateTypeEnum = OperateTypeEnum.RULE_DELETE;
                }
                formDataDeleteBatchVO.setDeleteIds(dataIdList);
                // paas记录日志(有名称的格式为编号(名称)，无名称的格式为编号)
                String logMemo = StringUtils.join(titleList, "，");
                if(dataIdList.size() > 1 ){
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, paasFormEntityExt.getName(), dataIdList.size());
                    List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    InfoArrPojo infoArrPojo = new InfoArrPojo();
                    infoArrPojo.setTitle(paasFormEntityExt.getName());
                    infoArrPojo.setContent(logMemo);
                    infoArrPojoList.add(infoArrPojo);
                    mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM_DATA, operateTypeEnum,
                            "", "", memo, formDataDeleteBatchDTO.getHttpHeader());
                } else if (Objects.equals(dataIdList.size(), 1)){
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, paasFormEntityExt.getName(), logMemo);
                    mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM_DATA, operateTypeEnum,
                            dataIdList.get(0).toString(), logMemo, memo, formDataDeleteBatchDTO.getHttpHeader());
                }
            }

            AnalysisDataDTO analysisDataDTO = new AnalysisDataDTO();
            BeanUtil.copyProperties(formDataDeleteBatchDTO,analysisDataDTO);
            dynamicHelp.deleteLinkData(corpid,saasMark,businessType,dataIdList,userId,userName,formId,paasFormDataEntityExtList,
                    explainMap,analysisDataDTO);

            List<Long> deleteIds = formDataDeleteBatchVO.getDeleteIds();
            // 低代码服务请求
            lowCodeExecuteService(deleteIds, formDataDeleteBatchDTO.getSaasMark(), formDataDeleteBatchDTO.getBusinessType(), formDataDeleteBatchDTO.getFormId(), corpid);

            //是否启用新工作流
            if (isEnableNewWorkflow(formDataDeleteBatchDTO, formDataDeleteBatchVO, deleteIds, WorkflowOperateEnum.DELETE)) {
                // 业务规则逻辑 start
                inactiveRule(formDataDeleteBatchDTO, businessRules, deleteIds);
                return formDataDeleteBatchVO;
            }

            // 业务规则
            inactiveRule(formDataDeleteBatchDTO, businessRules, deleteIds);
            // 富文本
            deleteRichText(formDataDeleteBatchDTO, deleteIds);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("listBatchServiceImpl.deleteBatch 执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formDataDeleteBatchVO;
    }

    /**
     * 删除富文本
     *
     * @param dto
     * @param deleteIds
     */
    private void deleteRichText(FormDataDeleteBatchDTO dto, List<Long> deleteIds) {
        if (CollectionsUtil.isNotEmpty(deleteIds)){
            richTextService.operateBatch(new FormRichTextBatchDTO(dto.getCorpid(), dto.getFormId(),
                    dto.getBusinessType(), dto.getSaasMark(), deleteIds, DelEnum.NORMAL.getDel(), DelEnum.DELETE.getDel()));
        }
    }

    /**
     * 失效时触发业务规则
     * @param formDataDeleteBatchDTO
     * @param businessRules
     */
    private void inactiveRule(FormDataDeleteBatchDTO formDataDeleteBatchDTO, String businessRules, List<Long> deleteIds) throws XbbException {
        // 业务规则逻辑 start
        if (!Objects.equals(1, formDataDeleteBatchDTO.getIsBusinessRule())
                && Objects.equals("1", businessRules) && CollectionsUtil.isNotEmpty(deleteIds)) {
            InactiveRuleByDeleteBatchDTO inactiveRuleDTO = new InactiveRuleByDeleteBatchDTO();
            BeanUtil.copyProperties(formDataDeleteBatchDTO, inactiveRuleDTO);
            inactiveRuleDTO.setFormDataIdList(deleteIds);
            formDataInactiveRuleByDeleteBatchHelp.inactiveRuleByDeleteBatch(inactiveRuleDTO);
        }
        // 业务规则逻辑 end
    }

    @Override
    public FormDataUpdateBatchVO updateBatch(FormDataUpdateBatchDTO formDataUpdateBatchDTO) throws XbbException {
        FormDataUpdateBatchVO formDataUpdateBatchVO = new FormDataUpdateBatchVO();
        try {
            // 校验编辑权限--表单级别的校验
            VerifyUpdatePermissionDTO updatePermissionDTO = new VerifyUpdatePermissionDTO();
            BeanUtil.copyProperties(formDataUpdateBatchDTO, updatePermissionDTO);
            ProPermissionHelp.verifyEditPermission(updatePermissionDTO);
            Integer saasMark = formDataUpdateBatchDTO.getSaasMark();
            Integer isBatch = formDataUpdateBatchDTO.getIsBatch();
            BusinessBatchEditService businessBatchEditService = businessBatchFactory.batchEdit(saasMark, formDataUpdateBatchDTO.getBusinessType());
            if (Objects.nonNull(businessBatchEditService)) {
                return businessBatchEditService.updateBatch(formDataUpdateBatchDTO);
            }
            //经销商业务改businessType
            Integer distributorMark = formDataUpdateBatchDTO.getDistributorMark();
            // 原数据类型
            Integer businessType = formDataUpdateBatchDTO.getBusinessType();
            if (Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode())){
                formDataUpdateBatchDTO.setBusinessType(XbbRefTypeEnum.transferBusinessType4Distributor(businessType,distributorMark));
            }
            List<Long> dataIdList = formDataUpdateBatchDTO.getDataIdList();
            String corpid = formDataUpdateBatchDTO.getCorpid();
            Long formId = formDataUpdateBatchDTO.getFormId();
            Long menuId = formDataUpdateBatchDTO.getMenuId();
            UserVO loginUser = formDataUpdateBatchDTO.getLoginUser();

            //拼装校验参数
            Map<Long, List<String>> ownerIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, List<String>> coUserIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            businessUserTeamHelp.getUserIdMapSetShow(new HashSet<>(), dataIdList, corpid, businessType, false, ownerIdMap, coUserIdMap, DelEnum.NORMAL.getDel());
            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                if (Objects.equals(formId, 0L)) {
                    //工单全部列表, 快速编辑处理
                    if (dataIdList != null && dataIdList.size() < 1) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
                    }
                    WorkOrderEntity workOrderEntity = workOrderModel.getByKey(dataIdList.get(0), corpid);
                    formId = workOrderEntity.getFormId();
                }
                WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(formId, corpid);
                BeanUtil.copyProperties(workOrderExplainEntity, paasFormExplainEntity);
            } else {
                paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
            }
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains());
            // 校验数据权限--数据级别的校验
            if (Objects.equals(isBatch, BasicConstant.ZERO) || Objects.equals(isBatch, BasicConstant.TWO)){
                PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormData(corpid, saasMark, businessType, dataIdList.get(0));
                if (Objects.isNull(paasFormDataEntityExt)){
                    return new FormDataUpdateBatchVO();
                }
                FormDataDetailDTO formDataDetailDTO = new FormDataDetailDTO(dataIdList.get(0), saasMark, businessType, menuId, paasFormDataEntityExt.getCreatorId(), loginUser);
                paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
                paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
                VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
                boolean hasDataPermission = Objects.equals(isBatch, BasicConstant.ZERO) ?
                        commonPermissionHelp.checkEditPermission(formDataDetailDTO, verifyUpdatePermissionDTO, explainMap) : commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
                if (!hasDataPermission){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), OperateTypeEnum.EDIT.getName()));
                }
            }else{
                List<PaasFormDataEntityExt> paasFormDataEntityExtList = formDataHelp.getByDataIdList(formDataUpdateBatchDTO.getDataIdList(), businessType, saasMark, formDataUpdateBatchDTO.getFormId(), corpid);
                List<Long> errorDataIdList = new ArrayList<>();
                //数据库获取相关规则
                List<ShareRuleEntity> ruleEntities = sharePermissionHelp.getRuleEntities(corpid, formDataUpdateBatchDTO.getFormId(), loginUser.getUserId());
                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
                    Long dataId = paasFormDataEntityExt.getId();
                    paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(dataId));
                    paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(dataId));
                    FormDataDetailDTO formDataDetailDTO = new FormDataDetailDTO(dataId, saasMark, businessType, menuId, paasFormDataEntityExt.getCreatorId(), loginUser);
                    VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
                    verifyUpdatePermissionDTO.setRuleEntities(ruleEntities);
                    boolean hasDataPermission = commonPermissionHelp.checkEditPermission(formDataDetailDTO, verifyUpdatePermissionDTO, explainMap);
                    if (!hasDataPermission){
                        errorDataIdList.add(dataId);
                    }
                }
                if(CollectionUtils.isNotEmpty(errorDataIdList)){
                    dataIdList.removeIf(errorDataIdList :: contains);
                }
            }
            if(CollectionUtils.isEmpty(dataIdList)){
                return formDataUpdateBatchVO;
            }
            PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();


            List<AttrValuePojo> fieldEditedList = formDataUpdateBatchDTO.getFieldEditedList();
            Map<String,Object>  editedAttr2ValueMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<String,Object>  dummyAttr2ValueMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<String> attrList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (AttrValuePojo attrValuePojo : fieldEditedList) {
                String attr = attrValuePojo.getAttr();
                Object value = attrValuePojo.getValue();
                editedAttr2ValueMap.put(attr, value);
                Object dummyValue = CloneUtil.deepClone(value);
                dummyAttr2ValueMap.put(attr,dummyValue);
                attrList.add(attr);
            }

            Map<String, FieldAttrEntity> editedFieldExplainMap = ExplainUtil.getExplainMapByAttrList(paasFormExplainEntity.getExplains(), attrList);

            filterValue4UpdateBatch(editedAttr2ValueMap, editedFieldExplainMap);
            formDataUpdateBatchDTO.judgeIsFieldDependence(editedFieldExplainMap);

            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                //工单
                WorkOrderFormEntity workOrderFormEntity = workOrderFormModel.getByKey(formId, corpid);
                BeanUtil.copyProperties(workOrderFormEntity, paasFormEntityExt);
            } else {
                paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
            }
            if(Objects.isNull(paasFormEntityExt)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            String businessRules = paasFormEntityExt.getBusinessRules();

            // 校验不可重复的单条数据
            for (String attr : editedAttr2ValueMap.keySet()) {
                FieldAttrEntity fieldAttrEntity = editedFieldExplainMap.get(attr);
                if (Objects.isNull(fieldAttrEntity)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                }
                if (Objects.equals(1, fieldAttrEntity.getNoRepeat()) && formDataUpdateBatchDTO.getDataIdList().size() > 1) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.THE_FIELD_NOT_EDIT_BATCH);
                }
            }
            // 校验单条或多条数据的 提交格式
            for (Long dataId : formDataUpdateBatchDTO.getDataIdList()) {
                ValidateDataDTO validateDataDTO = new ValidateDataDTO();
                BeanUtil.copyProperties(formDataUpdateBatchDTO, validateDataDTO);
                JSONObject data = new JSONObject();
                for (Map.Entry<String, Object> av : editedAttr2ValueMap.entrySet()) {
                    data.put(av.getKey(), av.getValue());
                }
                validateDataDTO.setData(data);
                validateDataDTO.setDataId(dataId);
                validateDataDTO.setExplainMap(editedFieldExplainMap);
                formDataValidateDataHelp.validateData(validateDataDTO);
            }
            // 获取数据
            List<PaasFormDataEntityExt> list = proFormDataService.dataListAndSubDataList(corpid, saasMark, formDataUpdateBatchDTO.getBusinessType(), formId, dataIdList);
            //判断是否结账中
            judgeIsSettleAccounts(corpid, businessType, list);

            // 是否有编辑权限，需要对每条数据进行
            // 字段可见可编辑和高级可见可编辑的判断--字段级别的校验
            checkEditPermission(new ArrayList<>(editedFieldExplainMap.values()), formDataUpdateBatchDTO, list);

            if (commonHelp.isOpenWorkFlow(formDataUpdateBatchDTO.getCorpid())) {
                boolean editAfterFinished = workflowHelp.getEditAfterFinished(formDataUpdateBatchDTO.getCorpid(), formDataUpdateBatchDTO.getFormId(), formDataUpdateBatchDTO.getBusinessType(), saasMark, loginUser);
                // 审批后能否编辑
                paasProcessTemplateModel.checkEditAfterFinished(editAfterFinished, list);
            } else {
                // 审批通过后是否允许编辑
                boolean editAfterFinished = paasProcessTemplateModel.getEditAfterFinished(formDataUpdateBatchDTO.getAppId(), menuId,formDataUpdateBatchDTO.getFormId(), loginUser);
                // 审批后能否编辑
                paasProcessTemplateModel.checkEditAfterFinished(editAfterFinished, list);
            }

            // 设置修改后的数据以及 LogValue (解析不同的数据结构)
            setBatchEditDataAndLog(editedAttr2ValueMap, dummyAttr2ValueMap, editedFieldExplainMap, formDataUpdateBatchDTO);

            if (SaasMarkEnum.SAAS.getCode().equals(saasMark)) {
                Integer fieldType = formDataUpdateBatchDTO.getFieldType();
                XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(formDataUpdateBatchDTO.getBusinessType());
                validateSaasFieldEditable(fieldType, xbbRefTypeEnum, editedAttr2ValueMap, editedFieldExplainMap);

                batchEditAttr(formDataUpdateBatchDTO, xbbRefTypeEnum);
                //添加项目日志(所有操作都走该方法，需要判断模块是否需要添加动态日志)
                updateBatchDynamic(formDataUpdateBatchDTO);
            } else {
                Map<String, FieldAttrEntity> paasExplainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
                proFormDataService.updateBatch(formDataUpdateBatchDTO, paasFormEntityExt, paasExplainMap);
            }

            //设置返回值
            List<AttrValuePojo> changedValueList = ProSaveHelp.analysisData(dummyAttr2ValueMap, editedFieldExplainMap, corpid);
            formDataUpdateBatchVO.setChangedValueList(changedValueList);

            if (isEnableNewWorkflow(formDataUpdateBatchDTO, list)) {
                // 业务规则逻辑 start
                startActiveRule(businessRules, formDataUpdateBatchDTO, list);
                return formDataUpdateBatchVO;
            }

            // 业务规则逻辑 start
            startActiveRule(businessRules, formDataUpdateBatchDTO, list);
            // 业务规则逻辑 end
            // 记录日志
            /*String userId = formDataUpdateBatchDTO.getUserId();
            String loginUserName = formDataUpdateBatchDTO.getLoginUserName();
            String memo = String.format(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_BATCH_ATTR, loginUserName, "", formDataUpdateBatchDTO.getAttr(), formDataUpdateBatchDTO.getValue());
            mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.PAAS_FORM_DATA, OperateTypeEnum.EDIT, formDataUpdateBatchDTO.getAppId().toString(), "", memo, formDataUpdateBatchDTO.getHttpHeader());
*/
        } catch (XbbException e){
            throw e;
        } catch (Exception e) {
            LOG.error("listBatchServiceImpl.updateBatch  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formDataUpdateBatchVO;
    }


    private void validateSaasFieldEditable(Integer fieldType, XbbRefTypeEnum xbbRefTypeEnum, Map<String, Object> editedAttr2ValueMap, Map<String, FieldAttrEntity> editedFieldExplainMap) throws XbbException {
        Set<String> saasEditAttrSet = null;
        Set<Integer> editAttrFieldTypeSet = null;
        for (String attr : editedAttr2ValueMap.keySet()) {
            FieldAttrEntity fieldAttrEntity = editedFieldExplainMap.get(attr);
            if (Objects.equals(0, fieldAttrEntity.getIsRedundant())) {
                if (Objects.isNull(saasEditAttrSet)) {
                    saasEditAttrSet = ExplainUtil.getSaasEditAttr(xbbRefTypeEnum);
                    editAttrFieldTypeSet = EditFieldTypeEnum.getEditFieldTypeSet();
                }
                // 可编辑字段列表不为空，并且包含该字段
                boolean saasEditAttr = !saasEditAttrSet.isEmpty() && !saasEditAttrSet.contains(attr);
                if (saasEditAttr
                        || !editAttrFieldTypeSet.contains(fieldType)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EDIT);
                }
            }
        }
    }

    /**
     * 过滤 单选、复选框、下拉框、下拉复选  、应收账期等
     * @param editedAttr2ValueMap
     * @param editedFieldExplainMap
     */
    private void filterValue4UpdateBatch(Map<String, Object> editedAttr2ValueMap, Map<String, FieldAttrEntity> editedFieldExplainMap) throws XbbException {
        for (Map.Entry<String, Object> item : editedAttr2ValueMap.entrySet()) {
            Object value = ProSaveHelp.getValue(item.getValue(), item.getKey(), editedFieldExplainMap);
            item.setValue(value);
        }
    }

    /**
     * 判断是否结账中
     * @param corpid
     * @param businessType
     * @param list
     * @throws XbbException
     */
    private void judgeIsSettleAccounts(String corpid, Integer businessType, List<PaasFormDataEntityExt> list) throws XbbException {
        if (!ProductConstant.EFFECT_PRODUCT_COST_AND_STOCK.contains(businessType)) {
            return;
        }
        for (PaasFormDataEntityExt paasFormDataEntityExt : list) {
            JSONObject data = paasFormDataEntityExt.getData();
            Long date = data.getLong(InstockEnum.TIME.getAttr());
            //结账中校验
            String redisHelperValue = paasRedisHelper.getValue(RedisPrefixConstant.SETTLE_ACCOUNTS, corpid);
            if (StringUtil.isNotEmpty(redisHelperValue)) {
                if (date <= DateTimeUtil.getTodayEndInt(Long.valueOf(redisHelperValue))) {
                    throw new XbbException(SettleAccountErrorCodeEnum.API_ERROR_254007);
                }
            }
            SettleAccountsEntity accountsEntity = settleAccountsModel.getLastSettleAccounts(corpid);
            //校验日期是否受结账限制
            if (Objects.nonNull(accountsEntity) && Objects.nonNull(accountsEntity.getCheckOutTime())) {
                if (date <= DateTimeUtil.getTodayEndInt(accountsEntity.getCheckOutTime())) {
                    throw new XbbException(OutstockErrorCodeEnum.API_ERROR_212051);
                }
            }
        }
    }

    /**
     * 批量更新动态
     * @param formDataUpdateBatchDTO
     */
    private void updateBatchDynamic(FormDataUpdateBatchDTO formDataUpdateBatchDTO){
        if (!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), formDataUpdateBatchDTO.getDistributorMark()) && !Objects.equals(formDataUpdateBatchDTO.getIsRecordDynamic(), 0)) {
            MainBusinessDynamicStrategy dynamicStrategy = dynamicStrategyFactory.getMainBusinessDynamicStrategyByBusinessType(formDataUpdateBatchDTO.getBusinessType());
            dynamicStrategy.batchUpdate(new DynamicUpdateBatchDTO(formDataUpdateBatchDTO, formDataUpdateBatchDTO.getDataIdList()));
        }
    }

    private void startActiveRule(String businessRules, FormDataUpdateBatchDTO formDataUpdateBatchDTO, List<PaasFormDataEntityExt> list) throws XbbException{
        // 业务规则逻辑 start
        if(Objects.equals("1", businessRules)){

            ActiveRuleByUpdateBatchDTO activeRuleByUpdateBatchDTO = new ActiveRuleByUpdateBatchDTO();
            BeanUtil.copyProperties(formDataUpdateBatchDTO, activeRuleByUpdateBatchDTO);
            activeRuleByUpdateBatchDTO.setFormDataIdList(formDataUpdateBatchDTO.getDataIdList());
            activeRuleByUpdateBatchDTO.setEditFlag(1);
            activeRuleByUpdateBatchDTO.setOldDataList(list);
            formDataActiveRuleByUpdateBatchHelp.activeRuleByUpdateBatch(activeRuleByUpdateBatchDTO);
        }
    }
    @Override
    public FollowVO getLastFollow(ListBatchDTO listBatchDTO) throws XbbException{
        if (listBatchDTO.getDataIdList().size() > 1){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        CustomerCommunicateEnum anEnum = CustomerCommunicateEnum.CUSTOMER_NAME;
        if (Objects.equals(listBatchDTO.getBusinessType(), XbbRefTypeEnum.CLUE.getCode())) {
            anEnum = CustomerCommunicateEnum.COMMUNICATE_BUSINESS;
            boolQueryBuilder.filter(termQuery(CustomerCommunicateEnum.getEsAttr4Keyword(CustomerCommunicateEnum.COMMUNICATE_BUSINESS_TYPE), XbbRefTypeEnum.CLUE.getCode()));
        }
        String corpid = listBatchDTO.getCorpid();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termQuery(CustomerCommunicateEnum.getEsAttr4Keyword(anEnum),listBatchDTO.getDataIdList().get(0)));
        boolQueryBuilder.filter(termQuery("del",0));
        boolQueryBuilder.filter(termQuery("logType", 0));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE.getType()));
        //需要加上数据权限的判断
        if (!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), listBatchDTO.getDistributorMark())) {
            DetailCommunicateDTO detailCommunicateDTO = new DetailCommunicateDTO();
            BeanUtil.copyProperties(listBatchDTO, detailCommunicateDTO);
            detailCommunicateDTO.setParentBusinessType(listBatchDTO.getBusinessType());
            detailCommunicateDTO.setParentId(listBatchDTO.getDataIdList().get(BasicConstant.ZERO));
            detailTabDataPermissionHelp.detailCustomerCommunicateDataFilter(detailCommunicateDTO, boolQueryBuilder,XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode());
        }
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE.getIndex());
        sourceBuilder.sort(new FieldSortBuilder("data." + CustomerCommunicateEnum.COMMUNICATE_TIME.getAttr()).order(SortOrder.DESC));
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder,0,2);
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        List<PaasFormDataEntityExt> resultList = esEntities.getContent();
        if (resultList.isEmpty()){
            return new FollowVO();
        }
        List<FollowPojo> list = new ArrayList<>();
        List<ItemPoJo> itemPoJoList = dataDictionaryModel.getDictionaryList4Saas(DictionaryEnum.COMMUNICATE_TYPE,corpid,resultList.get(0).getFormId());
        Map<String,String> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ItemPoJo itemPoJo : itemPoJoList){
            map.put(itemPoJo.getValue().toString(),itemPoJo.getText());
        }
        for (PaasFormDataEntityExt entity : resultList){
            FollowPojo followPojo = new FollowPojo();
            followPojo.setId(entity.getDataId());
            JSONObject data = entity.getData();
            followPojo.setMemo(data.getString(CustomerCommunicateEnum.MEMO.getAttr()));
            followPojo.setTime(DateTimeUtil.getStringEpochSecond(data.getLong(CustomerCommunicateEnum.COMMUNICATE_TIME.getAttr()),DateTimeUtil.SDFYMDHM));
            //仅两个,循环一下
            UserEntity userEntity = userModel.getByKeyIngoreDel(entity.getCreatorId(),corpid);
            if (Objects.isNull(userEntity)) {
                followPojo.setUserName("");
            }else {
                followPojo.setUserName(userEntity.getName());
            }
            followPojo.setType(map.getOrDefault(data.getString(CustomerCommunicateEnum.TYPE.getAttr()),""));
            list.add(followPojo);
        }
        FollowVO followVO = new FollowVO();
        followVO.setList(list);
        return followVO;
    }

    @Override
    public BaseVO setProductionStatus(ProductionStatusDTO productionStatusDTO) throws XbbException{
        //校验表单编辑权限
        VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO();
        BeanUtil.copyProperties(productionStatusDTO, verifyUpdatePermissionDTO);
        ProPermissionHelp.verifyEditPermission(verifyUpdatePermissionDTO);
        Integer businessType = productionStatusDTO.getBusinessType();
        //获取数据
        String corpid = productionStatusDTO.getCorpid();
        UserVO loginUser = productionStatusDTO.getLoginUser();
        List<Long> dataIdList = productionStatusDTO.getDataIdList();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put(StringConstant.IDIN, dataIdList);
        param.put("flowStatusIn", FlowStatusEnum.getStatisticType());
        List<ProductionOrderEntityExt> productionOrderList = productionOrderModel.findEntitys(param);
        Map<Long, List<String>> ownerIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        businessUserTeamHelp.getUserIdMapSetShow(new HashSet<>(), dataIdList, corpid, businessType, false, ownerIdMap, coUserIdMap, DelEnum.NORMAL.getDel());
        //单条操作,校验数据权限(团队权限&共享权限)
        if (Objects.equals(productionStatusDTO.getIsBatch(), BasicConstant.ZERO)){
            ProductionOrderEntityExt paasFormDataEntityExt = productionOrderList.get(0);
            paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
            paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
            verifyUpdatePermissionDTO.setPaasFormDataEntityExt(paasFormDataEntityExt);
            boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);;
            if (!hasDataPermission){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, SystemErrorCodeEnum.API_ERROR_100050.getMsg(), I18nMessageUtil.getMessage(CommonConstant.EDIT));
            }
        }else{
            List<PaasFormDataEntityExt> paasFormDataEntityExtList = formDataHelp.getByDataIdList(dataIdList, businessType, productionStatusDTO.getSaasMark(), productionStatusDTO.getFormId(), corpid);
            List<Long> errorDataIdList = new ArrayList<>();
            //数据库获取相关规则
            List<ShareRuleEntity> ruleEntities = sharePermissionHelp.getRuleEntities(corpid, productionStatusDTO.getFormId(), loginUser.getUserId());
            for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
                paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
                paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
                verifyUpdatePermissionDTO.setPaasFormDataEntityExt(paasFormDataEntityExt);
                boolean hasDataPermission = commonPermissionHelp.checkPermission(verifyUpdatePermissionDTO);
                if(!hasDataPermission){
                    verifyUpdatePermissionDTO.setRuleEntities(ruleEntities);
                    hasDataPermission = sharePermissionHelp.verifySharePermission4EditWithRuleEngine(verifyUpdatePermissionDTO);
                }
                if (!hasDataPermission){
                    errorDataIdList.add(paasFormDataEntityExt.getId());
                }
            }
            if(CollectionUtils.isNotEmpty(errorDataIdList)){
                dataIdList.removeIf(errorDataIdList :: contains);
            }
        }
        if (productionOrderList.size() != dataIdList.size()) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200023);
        }
        ProductionOrderStatusEnum productionOrderStatusEnum = ProductionOrderStatusEnum.getByCode(productionStatusDTO.getStatus());
        JSONObject jsonObject = new JSONObject();
        switch (productionOrderStatusEnum) {
            case UNFINISHED:
                //重启
                jsonObject.put(ProductionOrderEnum.STATUS.getAttr(), productionOrderStatusEnum.getCode());
                jsonObject.put(ProductionOrderEnum.COMPLETE_TIME.getAttr(), 0);
                jsonObject.put(ProductionOrderEnum.CLOSE_TIME.getAttr(), 0);
                break;
            case FINISHED:
                //完成
                jsonObject.put(ProductionOrderEnum.STATUS.getAttr(), productionOrderStatusEnum.getCode());
                jsonObject.put(ProductionOrderEnum.COMPLETE_TIME.getAttr(), DateTimeUtil.getInt());
                break;
            case CLOSED:
                //关闭
                jsonObject.put(ProductionOrderEnum.STATUS.getAttr(), productionOrderStatusEnum.getCode());
                jsonObject.put(ProductionOrderEnum.CLOSE_TIME.getAttr(), DateTimeUtil.getInt());
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        proUpdateHelp.updateByIds(businessType,corpid,dataIdList,jsonObject);
        return new BaseVO();
    }

    @Override
    @Transactional(rollbackFor = XbbException.class)
    public SetPaymentBatchVO setStatus(ListBatchDTO listBatchDTO) throws XbbException {
        SetPaymentBatchVO setPaymentBatchVO ;
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(listBatchDTO.getBusinessType());
        switch (xbbRefTypeEnum) {
            case PAYMENT:
                setPaymentBatchVO = setPaymentStatus(listBatchDTO);
                break;
            case PAY_PLAN:
                setPaymentBatchVO = setPayPlanStatus(listBatchDTO);
                break;
            default:
                throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        return setPaymentBatchVO;
    }

    @Override
    @Transactional(rollbackFor = XbbException.class)
    public SetPaymentBatchVO setPaymentStatus(ListBatchDTO listBatchDTO) throws XbbException {
        SetPaymentBatchVO setPaymentBatchVO = new SetPaymentBatchVO();
        if (! Objects.equals(listBatchDTO.getBusinessType(),XbbRefTypeEnum.PAYMENT.getCode())){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        List<Long> dataIdList = listBatchDTO.getDataIdList();
        String corpid = listBatchDTO.getCorpid();
        String userId = listBatchDTO.getUserId();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("del", 0);
        params.put("businessType", XbbRefTypeEnum.PAYMENT_SHEET.getCode());
        params.put("corpid", corpid);
        params.put("distributorMark", listBatchDTO.getDistributorMark());
        //查询回款单的paasForm信息
        List<PaasFormEntityExt> paasFormEntityExts = paasFormModel.findEntitys(params);
        if (CollectionsUtil.isNotEmpty(paasFormEntityExts)) {
            params.put("formId", paasFormEntityExts.get(BasicConstant.ZERO).getId());
        }
        params.put("enable", 1);
        params.put(ParameterConstant.COLUMNS, "enable");

        if (commonHelp.isOpenWorkFlow(corpid)) {
            List<WorkflowEntity> workflowEntities = workflowModel.findEntitys(params);
            if (CollectionsUtil.isNotEmpty(workflowEntities)) {
                throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208043);
            }
        } else {
            List<PaasProcessTemplateEntityExt> processList = paasProcessTemplateModel.list(params);
            if ( !processList.isEmpty() && Objects.equals(processList.get(0).getEnable(), 1) ) {
                throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208043);
            }
        }

        FundAccountEntity fundAccount = fundAccountModel.getByIdCorpid(listBatchDTO.getAccountId(),corpid);
        if ( Objects.isNull(fundAccount) ) {
            throw new XbbException(FundAccountErrorCodeEnum.API_ERROR_1000006);
        }
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(),dataIdList));
        boolQueryBuilder.filter(termQuery("del",0));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PAYMENT.getType()));
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PAYMENT.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder,0,dataIdList.size());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        List<PaasFormDataEntityExt> paymentList = esEntities.getContent();
        Set<Long> contractIdList = new HashSet<>();
        Map<Long, Double> paymentTotalAmountMap = new HashMap<>();
        Double paymentAmount = 0D;
        Map<Long, List<Long>> paymentListMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, PaasFormDataEntityExt> paymentMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //获取应收款的编号
        List<String> paymentNoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt entity : paymentList){
            JSONObject data = entity.getData();
            Long contractId = FastJsonHelper.getLongOrDefaultFromFormData(data, PaymentEnum.CONTRACT.getAttr(), -1L);
            String status = FastJsonHelper.getStringOrDefaultFromFormData(data, PaymentEnum.STATUS.getAttr(), "");
            //未收款/部分收款状态应收款状态校验
            if (!Objects.equals(PaymentStatusEnum.UN_RECEIVABLES.getCode(), status) && !Objects.equals(PaymentStatusEnum.PARTIAL_RECEIPTS.getCode(), status)) {
                throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208028);
            }
            //统计归纳一下每个合同本次的回收金额
            paymentAmount = paymentTotalAmountMap.get(contractId) == null ? 0D : paymentTotalAmountMap.get(contractId);
            Double unAmount = getDoubleOrDefaultFromFormData(data, PaymentEnum.UN_AMOUNT.getAttr(), 0D);
            paymentAmount = Arith.add(paymentAmount, unAmount);
            paymentTotalAmountMap.put(contractId, paymentAmount);
            List<Long> paymentIdList = paymentListMap.get(contractId) == null ? new ArrayList<>() : paymentListMap.get(contractId);
            paymentIdList.add(entity.getId());
            paymentListMap.put(contractId, paymentIdList);
            contractIdList.add(contractId);
            paymentMap.put(entity.getId(), entity);

            paymentNoList.add(entity.getSerialNo());
        }
        sourceBuilder = new SearchSourceBuilder();
        boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(),contractIdList));
        boolQueryBuilder.filter(termQuery("del",0));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
        sourceBuilder.query(boolQueryBuilder);
        searchRequest.indices(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
        pageRequest =  EsUtil.setPage(sourceBuilder,0,dataIdList.size());
        searchRequest.source(sourceBuilder);
        esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        List<PaasFormDataEntityExt> contractList = esEntities.getContent();
        Map<String,PaasFormDataEntityExt> contractMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> removeContractPaymentList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt entity : contractList){
            contractMap.put(entity.getDataId().toString(),entity);
            Double contractUnAmount = getDoubleOrDefaultFromFormData(entity.getData(), ContractEnum.UN_FINISH_AMOUNT.getAttr(), 0D);
            Double contractTotalUnAmount = paymentTotalAmountMap.get(entity.getDataId());
            if ( contractUnAmount < contractTotalUnAmount ) {
                List<Long> removePaymentIdList = paymentListMap.get(entity.getDataId());
                if ( CollectionsUtil.isNotEmpty(removePaymentIdList) ) {
                    removeContractPaymentList.addAll(removePaymentIdList);
                    dataIdList.removeAll(removePaymentIdList);
                }
            }
        }
        List<PaasFormDataEntityExt> removePaymentList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<PaasFormDataEntityExt> setPaymentList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if ( CollectionsUtil.isNotEmpty(removeContractPaymentList) ) {
            removeContractPaymentList.forEach(item->{
                removePaymentList.add(paymentMap.get(item));
            });
        }
        if ( CollectionsUtil.isNotEmpty(dataIdList) ) {
            dataIdList.forEach(item->{
                setPaymentList.add(paymentMap.get(item));
            });
        }
        Iterator<PaasFormDataEntityExt> iterator = setPaymentList.iterator();
        List<PaymentSheetEntityExt> paymentSheetEntityExtList = new ArrayList<>();
        Long now = DateTimeUtil.getInt();
        List<UpdateDataEntity> paymentUpdateList = new ArrayList<>();
        List<UpdateDataEntity> contractUpdateList = new ArrayList<>();
        Map<Long, UpdateDataEntity> contractUpdateIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Integer distributorMark = listBatchDTO.getDistributorMark();
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType4Distributor(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), corpid, distributorMark);
        Long formId = paasFormExplainEntity.getFormId();
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        List<String> paymentSheetNoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<FundAccountFlowEntity> fundAccountFlowEntities = new ArrayList<>();
        Map<Long, Double> fundAccountToAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        SheetTypeEnum sheetTypeEnum = SheetTypeEnum.WRITE_OFF;
        String sheetType = sheetTypeEnum.getCode();
        while (iterator.hasNext()){
            PaasFormDataEntityExt entity = iterator.next();
            JSONObject paymentData = entity.getData();
            String status = FastJsonHelper.getStringOrDefaultFromFormData(paymentData, PaymentEnum.STATUS.getAttr(), "");
            if (!Objects.equals(PaymentStatusEnum.UN_RECEIVABLES.getCode(), status) && !Objects.equals(PaymentStatusEnum.PARTIAL_RECEIPTS.getCode(), status)) {
                continue;
            }
            String contractIdStr = paymentData.getString(PaymentEnum.CONTRACT.getAttr());
            //应收款的未收金额为回款单的回款金额
            Double unAmount = paymentData.getDouble(PaymentEnum.UN_AMOUNT.getAttr());
            Double amount = paymentData.getDouble(PaymentEnum.AMOUNT.getAttr());
            Long paymentId = entity.getDataId();
            PaasFormDataEntityExt contract = contractMap.get(contractIdStr);
            if (Objects.isNull(contract)) {
                throw new XbbException(ContractErrorCodeEnum.API_ERROR_203001);
            }
            Long contractId = contract.getDataId();
            JSONObject contractData = contract.getData();
            PaymentSheetEntityExt paymentSheetEntityExt = new PaymentSheetEntityExt();
            BeanUtil.copyProperties(entity, paymentSheetEntityExt);
            paymentSheetEntityExt.setFormId(formId);
            paymentSheetEntityExt.setMenuId(paasFormExplainEntity.getMenuId());
            JSONObject data = SaasDataInitHelp.initPaymentSheet();
            data.put(PaymentSheetEnum.AMOUNT.getAttr(),unAmount);
            data.put(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr(),unAmount);
            data.put(PaymentSheetEnum.PAYMENT_TIME.getAttr(),now);
            data.put(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr(), sheetType);
            if (Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), distributorMark)) {
                //厂商端新建经销商类型回款单，且为已核销类型，则支付方式默认置为代客操作
                saasSaveHelp.handlePayMethod4Distributor(listBatchDTO.getPlatform(), data, sheetType, distributorMark);
            } else {
                data.put(PaymentSheetEnum.PAY_METHOD.getAttr(),paymentData.getString(PaymentEnum.PAYMENT_METHOD.getAttr()));
            }
            data.put(PaymentSheetEnum.CONTRACT.getAttr(), Collections.singletonList(contractId));
            data.put(PaymentSheetEnum.CONTRACT_LINK_TEXT.getAttr(), Collections.singletonList(contract.getSerialNo()));
            data.put(PaymentSheetEnum.PAYMENT.getAttr(), Collections.singletonList(paymentId));
            data.put(PaymentSheetEnum.PAYMENT_LINK_TEXT.getAttr(), Collections.singletonList(entity.getSerialNo()));
            data.put(PaymentSheetEnum.CUSTOMER_ID.getAttr(), paymentData.getLong(PaymentEnum.CUSTOMER.getAttr()));
            data.put(PaymentSheetEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), paymentData.getString(PaymentEnum.CUSTOMER_LINK_TEXT.getAttr()));
            data.put(PaymentSheetEnum.BELONG_ID.getAttr(), Collections.singletonList(contractData.getString(ContractEnum.SIGN_PERSON.getAttr())));
            data.put(PaymentSheetEnum.FUND_ACCOUNT.getAttr(), fundAccount.getId().toString());
            //编号获取
            String serialNo = saasSaveHelp.getSerialNo(explainList, formId, corpid);
            paymentSheetEntityExt.setSerialNo(serialNo);
            paymentSheetEntityExt.setData(data);
            String uuid = UUID.randomUUID().toString();
            paymentSheetEntityExt.setUuid(uuid);
            paymentSheetEntityExt.setAddTime(DateUtil.getNow());
            paymentSheetEntityExt.setUpdateTime(DateUtil.getNow());
            paymentSheetEntityExt.setCreatorId(userId);
            paymentSheetEntityExt.setAlone(SheetAloneEnum.NORMAL.getCode());
            paymentSheetEntityExtList.add(paymentSheetEntityExt);
            // 存下回款单编号
            paymentSheetNoList.add(serialNo);
            //应收款冗余字段更新
            paymentData.put(PaymentEnum.STATUS.getAttr(),PaymentStatusEnum.RECEIVABLES.getCode());
            paymentData.put(PaymentEnum.REAL_AMOUNT.getAttr(),unAmount);
            paymentData.put(PaymentEnum.UN_AMOUNT.getAttr(),0);
            paymentData.put(PaymentEnum.REAL_PAY_TIME.getAttr(), DateTimeUtil.getInt());
            paymentUpdateList.add(ExplainUtil.getUpdateData(paymentId,paymentData,corpid));
            //合同冗余字段更新
            Double finishAmount = contractData.getDouble(ContractEnum.FINISH_AMOUNT.getAttr());
            finishAmount = finishAmount == null ? 0D : finishAmount;
            Double contractAmount = contractData.getDouble(ContractEnum.AMOUNT.getAttr());
            contractAmount = contractAmount == null ? 0D : contractAmount;
            if (contractUpdateIdMap.get(contractId) != null) {
                UpdateDataEntity oldContractUpdateEntity = contractUpdateIdMap.get(contractId);
                List<UpdateDataValueEntity> oldResultUpdateEntity = oldContractUpdateEntity.getData();
                JSONObject oldContractData = ExplainUtil.getDataJsonByUpdateDataValue(oldResultUpdateEntity);
                finishAmount = oldContractData.getDouble(ContractEnum.FINISH_AMOUNT.getAttr());
                finishAmount = finishAmount == null ? 0D : finishAmount;
                contractAmount = oldContractData.getDouble(ContractEnum.AMOUNT.getAttr());
                contractAmount = contractAmount == null ? 0D : contractAmount;
                contractData.put(ContractEnum.FINISH_AMOUNT.getAttr(),Arith.add(finishAmount, unAmount));
                contractData.put(ContractEnum.UN_FINISH_AMOUNT.getAttr(),Arith.sub(Arith.sub(contractAmount , Arith.add(finishAmount , unAmount)), contractData.getDouble(ContractEnum.BAD_AMOUNT.getAttr())));
                contractData.put(ContractEnum.PAY_PERCENT.getAttr(),Arith.div(Arith.add(finishAmount , unAmount),contractAmount));
                UpdateDataEntity contractUpdateEntity = ExplainUtil.getUpdateData(contractId, contractData, corpid);
                contractUpdateList.remove(oldContractUpdateEntity);
                contractUpdateList.add(contractUpdateEntity);
                contractUpdateIdMap.put(contractId, contractUpdateEntity);
            } else {
                contractData.put(ContractEnum.FINISH_AMOUNT.getAttr(),Arith.add(finishAmount , unAmount));
                contractData.put(ContractEnum.UN_FINISH_AMOUNT.getAttr(),Arith.sub(contractAmount , Arith.sub(contractData.getDouble(ContractEnum.FINISH_AMOUNT.getAttr()) , contractData.getDouble(ContractEnum.BAD_AMOUNT.getAttr()))));
                contractData.put(ContractEnum.PAY_PERCENT.getAttr(),Arith.div(Arith.add(finishAmount , unAmount),contractAmount));
                UpdateDataEntity contractUpdateEntity = ExplainUtil.getUpdateData(contractId, contractData, corpid);
                contractUpdateList.add(contractUpdateEntity);
                contractUpdateIdMap.put(contractId, contractUpdateEntity);
            }
        }
        if(!paymentUpdateList.isEmpty()){
            paymentModel.updateBatch(paymentUpdateList,corpid);

            List<DataInfoDTO> dataInfoDTOs = new ArrayList<>();
            for (UpdateDataEntity paymentUpdate : paymentUpdateList) {
                DataInfoDTO dataInfoDTO = new DataInfoDTO();
                dataInfoDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                dataInfoDTO.setFormId(paymentUpdate.getFormId());
                dataInfoDTO.setDataId(paymentUpdate.getId());
                dataInfoDTOs.add(dataInfoDTO);
            }
        }
        Runnable runnable = () -> {
            try {
                if (!paymentSheetEntityExtList.isEmpty()) {
                    paymentSheetModel.insertBatch(paymentSheetEntityExtList);
                    //都是已核销类型回款单，不用判断类型
                    List<CreditCardBillInfoPojo> creditCardBillInfoList = new ArrayList<>();
                    for (PaymentSheetEntityExt paymentSheetEntityExt : paymentSheetEntityExtList) {
                        Long sheetId = paymentSheetEntityExt.getId();
                        JSONObject data = paymentSheetEntityExt.getData();
                        Long accountId = FastJsonHelper.getLongOrDefaultFromFormData(data, PaymentSheetEnum.FUND_ACCOUNT.getAttr(), 0L);
                        Double sheetAmount = getDoubleOrDefaultFromFormData(data, PaymentSheetEnum.AMOUNT.getAttr(), 0D);
                        //账户余额变动
                        fundAccountToAmountMap.merge(accountId, sheetAmount, Arith::add);
                        //流水表日志记录
                        FundAccountFlowEntity fundAccountFlowEntity = new FundAccountFlowEntity(corpid, DateTimeUtil.getInt(), paymentSheetEntityExt.getCreatorId(), FundAccountFlowTypeEnum.PAYMENT_SHEET.getCode(), sheetId, accountId, now, sheetAmount);
                        fundAccountFlowEntities.add(fundAccountFlowEntity);
                        //经销商类型回款单，则释放信用。
                        Long customerId = data.getLongValue(PaymentSheetDistributorEnum.DISTRIBUTOR_ID.getAttr());
                        String customerName = data.getString(PaymentSheetDistributorEnum.DISTRIBUTOR_NAME_LINK_TEXT.getAttr());
                        CreditCardBillInfoPojo infoPojo = new CreditCardBillInfoPojo(CreditCardBillTypeEnum.PAYMENT_SHEET.getCode(), sheetId, paymentSheetEntityExt.getSerialNo(), sheetAmount, customerId, customerName, XbbRefTypeEnum.PAYMENT_SHEET.getCode());
                        creditCardBillInfoList.add(infoPojo);
                    }
                    if (fundAccountFlowEntities.size() > 0) {
                        fundAccountFlowModel.insertBatch(fundAccountFlowEntities);
                    }
                    if (fundAccountToAmountMap.size() > 0) {
                        fundAccountService.saveBatchByPaymentSheetOrPaySheet(fundAccountToAmountMap);
                    }
                    Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMapByList(explainList);
                    //记录客户对账单
                    saasCustomerStatementHelper.save(XbbRefTypeEnum.PAYMENT_SHEET.getCode(), explainMap, paymentSheetEntityExtList, distributorMark);
                    List<Long> contractIdIn = new ArrayList<>();
                    Map<Long, List<Long>> idAndContractIdMap = new HashMap<>(paymentSheetEntityExtList.size());
                    JSONObject customerData = paymentSheetEntityExtList.get(0).getData();
                    Long customerId = FastJsonHelper.getLongOrDefaultFromFormData(customerData, PaymentSheetEnum.CUSTOMER_ID.getAttr(), 0L);
                    for ( PaymentSheetEntityExt paymentEntityExt : paymentSheetEntityExtList ) {
                        fundHelp.handleSheetIdAndContractIdMap(contractIdIn, idAndContractIdMap, paymentEntityExt, PaymentSheetEnum.CONTRACT.getAttr());
                    }
                    userTeamService.createPaymentSheetUser(corpid, customerId, contractIdIn, idAndContractIdMap, sheetTypeEnum, false);
                    if (Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode())) {
                        CreditCardBillDTO creditCardBillDTO = new CreditCardBillDTO(creditCardBillInfoList);
                        BeanUtil.copyProperties(listBatchDTO, creditCardBillDTO);
                        saasCreditHelper.addBatchCreditCardBill(creditCardBillDTO);
                    }
                }
                if (!contractUpdateList.isEmpty()){
                    contractModel.updateBatch(contractUpdateList,corpid);
                }
            } catch (XbbException e) {
                LOG.error("设置已收款中更新合同或新增回款单报错", e);
            }

        };
        threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);

        // 设置回款已收款日志
        String userName = listBatchDTO.getLoginUserName();
        String nameStr = StringUtils.join(paymentNoList, "，");
        if(paymentSheetEntityExtList.size() > 1){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_SET_PAYMENT_SHEET), userName, XbbRefTypeEnum.PAYMENT.getName(), paymentSheetEntityExtList.size());
            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            InfoArrPojo infoArrPojo = new InfoArrPojo();
            infoArrPojo.setTitle(PaymentSheetEnum.SHEET_NO.getAttrName());
            infoArrPojo.setContent(nameStr);
            infoArrPojoList.add(infoArrPojo);
            mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.PaymentManage, OperateTypeEnum.SET,
                    "", "", memo, listBatchDTO.getHttpHeader());
        } else if (Objects.equals(paymentSheetEntityExtList.size(), 1)){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_SET_PAYMENT_SHEET), userName, XbbRefTypeEnum.PAYMENT.getName(), nameStr);
            mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PaymentManage, OperateTypeEnum.SET,
                    paymentSheetEntityExtList.get(0).getDataId().toString(), nameStr, memo, listBatchDTO.getHttpHeader());
        }
        if ( CollectionsUtil.isNotEmpty(removeContractPaymentList) ) {
            List<String> errorDataList = new ArrayList<>();
            List<String> errorTypeList = new ArrayList<>();
            String errorDataMemo = String.format(I18nMessageUtil.getMessage(MessageConstant.CONTRACT_OVER_AMOUNT), removeContractPaymentList.size());
            removePaymentList.forEach(item->{
                errorDataList.add(item.getSerialNo());
            });
            errorTypeList.add(PaymentErrorCodeEnum.API_ERROR_208049.getMsg());
            setPaymentBatchVO.setErrorDataList(errorDataList);
            setPaymentBatchVO.setErrorTypeList(errorTypeList);
            setPaymentBatchVO.setErrorDataMemo(errorDataMemo);
        }
        return setPaymentBatchVO;
    }

    @Override
    @Transactional(rollbackFor = XbbException.class)
    public SetPaymentBatchVO setPayPlanStatus(ListBatchDTO listBatchDTO) throws XbbException {
        SetPaymentBatchVO setPaymentBatchVO = new SetPaymentBatchVO();
        if (! Objects.equals(listBatchDTO.getBusinessType(),XbbRefTypeEnum.PAY_PLAN.getCode())){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        List<Long> dataIdList = listBatchDTO.getDataIdList();
        String corpid = listBatchDTO.getCorpid();
        String userId = listBatchDTO.getUserId();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("del", 0);
        params.put("businessType", XbbRefTypeEnum.PAY_SHEET.getCode());
        params.put("corpid", corpid);
        params.put("enable", 1);
        params.put(ParameterConstant.COLUMNS, "enable");

        if (commonHelp.isOpenWorkFlow(corpid)) {
            List<WorkflowEntity> workflowEntities = workflowModel.findEntitys(params);
            if (CollectionsUtil.isNotEmpty(workflowEntities)) {
                throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208054);
            }
        } else {
            List<PaasProcessTemplateEntityExt> processList = paasProcessTemplateModel.list(params);
            if ( !processList.isEmpty() && Objects.equals(processList.get(0).getEnable(), 1) ) {
                throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208054);
            }
        }
        FundAccountEntity fundAccount = fundAccountModel.getByIdCorpid(listBatchDTO.getAccountId(),corpid);
        if ( Objects.isNull(fundAccount) ) {
            throw new XbbException(FundAccountErrorCodeEnum.API_ERROR_1000006);
        }
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(),dataIdList));
        boolQueryBuilder.filter(termQuery("del",0));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PAY_PLAN.getType()));
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PAY_PLAN.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder,0,dataIdList.size());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        List<PaasFormDataEntityExt> payPlanList = esEntities.getContent();
        Set<Long> purchaseIdList = new HashSet<>();
        Map<Long, Double> payPlanTotalAmountMap = new HashMap<>();
        Double payPlanAmount = 0D;
        Map<Long, List<Long>> payPlanListMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, PaasFormDataEntityExt> payPlanMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<FundAccountFlowEntity> fundAccountFlowEntities = new ArrayList<>();
        Map<Long, Double> fundAccountToAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //获取付款计划的编号
        List<String> payPlanNoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt entity : payPlanList){
            JSONObject data = entity.getData();
            Long purchaseId = FastJsonHelper.getLongOrDefaultFromFormData(data, PayPlanEnum.LINK_PURCHASE.getAttr(), -1L);
            String status = FastJsonHelper.getStringOrDefaultFromFormData(data, PayPlanEnum.STATUS.getAttr(), "");
            //未付款/部分付款状态付款计划状态校验
            if (!Objects.equals(PayPlanStatusEnum.UN_RECEIVABLES.getCode(), status) && !Objects.equals(PayPlanStatusEnum.PARTIAL_RECEIPTS.getCode(), status)) {
                throw new XbbException(PaymentErrorCodeEnum.API_ERROR_208051);
            }
            //统计归纳一下每个合同本次的回收金额
            payPlanAmount = payPlanTotalAmountMap.get(purchaseId) == null ? 0D : payPlanTotalAmountMap.get(purchaseId);
            Double unAmount = getDoubleOrDefaultFromFormData(data, PayPlanEnum.UN_AMOUNT.getAttr(), 0D);
            payPlanAmount = Arith.add(payPlanAmount, unAmount);
            payPlanTotalAmountMap.put(purchaseId, payPlanAmount);
            List<Long> paymentIdList = payPlanListMap.get(purchaseId) == null ? new ArrayList<>() : payPlanListMap.get(purchaseId);
            paymentIdList.add(entity.getId());
            payPlanListMap.put(purchaseId, paymentIdList);
            purchaseIdList.add(purchaseId);
            payPlanMap.put(entity.getId(), entity);
            payPlanNoList.add(entity.getSerialNo());
        }
        sourceBuilder = new SearchSourceBuilder();
        boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(),purchaseIdList));
        boolQueryBuilder.filter(termQuery("del",0));
        //限定连接值
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PURCHASE.getType()));
        sourceBuilder.query(boolQueryBuilder);
        searchRequest.indices(IndexTypeEnum.IDX_SAAS_PURCHASE.getIndex());
        pageRequest =  EsUtil.setPage(sourceBuilder,0,dataIdList.size());
        searchRequest.source(sourceBuilder);
        esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        List<PaasFormDataEntityExt> contractList = esEntities.getContent();
        Map<String,PaasFormDataEntityExt> contractMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> removePurchasePayPlanList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt entity : contractList){
            contractMap.put(entity.getDataId().toString(),entity);
            Double purchaseUnAmount = getDoubleOrDefaultFromFormData(entity.getData(), PurchaseEnum.UN_FINISH_AMOUNT.getAttr(), 0D);
            Double purchaseTotalUnAmount = payPlanTotalAmountMap.get(entity.getDataId());
            if ( purchaseUnAmount < purchaseTotalUnAmount ) {
                List<Long> removePayPlanIdList = payPlanListMap.get(entity.getDataId());
                if ( CollectionsUtil.isNotEmpty(removePayPlanIdList) ) {
                    removePurchasePayPlanList.addAll(removePayPlanIdList);
                    dataIdList.removeAll(removePayPlanIdList);
                }
            }
        }
        List<PaasFormDataEntityExt> removePayPlanList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<PaasFormDataEntityExt> setPayPlanList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if ( CollectionsUtil.isNotEmpty(removePurchasePayPlanList) ) {
            removePurchasePayPlanList.forEach(item->{
                removePayPlanList.add(payPlanMap.get(item));
            });
        }
        if ( CollectionsUtil.isNotEmpty(dataIdList) ) {
            dataIdList.forEach(item->{
                setPayPlanList.add(payPlanMap.get(item));
            });
        }
        Iterator<PaasFormDataEntityExt> iterator = setPayPlanList.iterator();
        List<PayPlanSheetEntityExt> paySheetEntityExtList = new ArrayList<>();
        Long now = DateTimeUtil.getInt();
        List<UpdateDataEntity> payPlanUpdateList = new ArrayList<>();
        List<UpdateDataEntity> purchaseUpdateList = new ArrayList<>();
        Map<Long, UpdateDataEntity> purchaseUpdateIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        PaasFormEntity paasFormEntity = paasFormModel.getByBusinessType(XbbRefTypeEnum.PAY_SHEET.getCode(),corpid);
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PAY_SHEET.getCode(), corpid);
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        List<String> paymentSheetNoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        while (iterator.hasNext()){
            PaasFormDataEntityExt entity = iterator.next();
            JSONObject payPlanData = entity.getData();
            String status = FastJsonHelper.getStringOrDefaultFromFormData(payPlanData, PayPlanEnum.STATUS.getAttr(), "");
            if (!Objects.equals(PayPlanStatusEnum.UN_RECEIVABLES.getCode(), status) && !Objects.equals(PayPlanStatusEnum.PARTIAL_RECEIPTS.getCode(), status)) {
                continue;
            }
            String purchaseIdStr = payPlanData.getString(PayPlanEnum.LINK_PURCHASE.getAttr());
            //付款计划的未收金额为付款单的付款金额
            Double unAmount = payPlanData.getDouble(PayPlanEnum.UN_AMOUNT.getAttr());
            Double amount = payPlanData.getDouble(PayPlanEnum.AMOUNT.getAttr());
            Long payPlanId = entity.getDataId();
            PaasFormDataEntityExt purchase = contractMap.get(purchaseIdStr);
            if (Objects.isNull(purchase)) {
                throw new XbbException(ContractErrorCodeEnum.API_ERROR_203001);
            }
            Long purchaseId = purchase.getDataId();
            JSONObject purchaseData = purchase.getData();
            PayPlanSheetEntityExt paySheetEntityExt = new PayPlanSheetEntityExt();
            BeanUtil.copyProperties(entity, paySheetEntityExt);
            paySheetEntityExt.setFormId(paasFormEntity.getId());
            paySheetEntityExt.setMenuId(paasFormEntity.getMenuId());
            JSONObject data = SaasDataInitHelp.initPayPlanSheet();
            data.put(PaySheetEnum.AMOUNT.getAttr(),unAmount);
            data.put(PaySheetEnum.WRITE_OFF_AMOUNT.getAttr(),unAmount);
            data.put(PaySheetEnum.REAL_PAY_TIME.getAttr(),now);
            data.put(PaySheetEnum.PAY_TYPE.getAttr(),payPlanData.getString(PayPlanEnum.PAYMENT_METHOD.getAttr()));
            data.put(PaySheetEnum.LINK_PURCHASE.getAttr(), Collections.singletonList(purchaseId));
            data.put(PaySheetEnum.PURCHASE_LINK_TEXT.getAttr(), Collections.singletonList(purchase.getSerialNo()));
            data.put(PaySheetEnum.PAY_PLAN.getAttr(), Collections.singletonList(payPlanId));
            data.put(PaySheetEnum.PAY_PLAN_LINK_TEXT.getAttr(), Collections.singletonList(entity.getSerialNo()));
            data.put(PaySheetEnum.LINK_SUPPLIER.getAttr(), payPlanData.getLong(PayPlanEnum.LINK_SUPPLIER.getAttr()));
            data.put(PaySheetEnum.SUPPLIER_LINK_TEXT.getAttr(), payPlanData.getString(PayPlanEnum.LINK_SUPPLIER_LINK_TEXT.getAttr()));
            data.put(PaySheetEnum.BELONG_ID.getAttr(), Collections.singletonList(purchaseData.getString(PurchaseEnum.SIGNER_ID.getAttr())));
            data.put(PaySheetEnum.PAY_SHEET_TYPE.getAttr(), PaySheetTypeEnum.WRITE_OFF_PAY.getCode());
            data.put(PaySheetEnum.FUND_ACCOUNT.getAttr(), fundAccount.getId().toString());
            //编号获取
            String serialNo = saasSaveHelp.getSerialNo(explainList, paasFormEntity.getId(), corpid);
            paySheetEntityExt.setSerialNo(serialNo);
            paySheetEntityExt.setData(data);
            String uuid = UUID.randomUUID().toString();
            paySheetEntityExt.setUuid(uuid);
            paySheetEntityExt.setAddTime(DateUtil.getNow());
            paySheetEntityExt.setUpdateTime(DateUtil.getNow());
            paySheetEntityExt.setCreatorId(userId);
            paySheetEntityExt.setAlone(SheetAloneEnum.NORMAL.getCode());
            paySheetEntityExtList.add(paySheetEntityExt);
            // 存下回款单编号
            paymentSheetNoList.add(serialNo);
            //付款计划冗余字段更新
            payPlanData.put(PayPlanEnum.STATUS.getAttr(),PayPlanStatusEnum.RECEIVABLES.getCode());
            payPlanData.put(PayPlanEnum.REAL_AMOUNT.getAttr(),amount);
            payPlanData.put(PayPlanEnum.UN_AMOUNT.getAttr(),0);
            payPlanData.put(PayPlanEnum.REAL_PAY_TIME.getAttr(), DateTimeUtil.getInt());
            payPlanUpdateList.add(ExplainUtil.getUpdateData(payPlanId,payPlanData,corpid));
            //合同冗余字段更新
            Double finishAmount = purchaseData.getDouble(PurchaseEnum.FINISH_AMOUNT.getAttr());
            finishAmount = finishAmount == null ? 0D : finishAmount;
            Double purchaseAmount = purchaseData.getDouble(PurchaseEnum.TOTAL_MONEY.getAttr());
            purchaseAmount = purchaseAmount == null ? 0D : purchaseAmount;
            if (purchaseUpdateIdMap.get(purchaseId) != null) {
                UpdateDataEntity oldPurchaseUpdateEntity = purchaseUpdateIdMap.get(purchaseId);
                List<UpdateDataValueEntity> oldResultUpdateEntity = oldPurchaseUpdateEntity.getData();
                JSONObject oldContractData = ExplainUtil.getDataJsonByUpdateDataValue(oldResultUpdateEntity);
                finishAmount = oldContractData.getDouble(PurchaseEnum.FINISH_AMOUNT.getAttr());
                finishAmount = finishAmount == null ? 0D : finishAmount;
                purchaseAmount = oldContractData.getDouble(PurchaseEnum.TOTAL_MONEY.getAttr());
                purchaseAmount = purchaseAmount == null ? 0D : purchaseAmount;
                purchaseData.put(PurchaseEnum.FINISH_AMOUNT.getAttr(),Arith.add(finishAmount, unAmount));
                purchaseData.put(PurchaseEnum.UN_FINISH_AMOUNT.getAttr(),Arith.sub(Arith.sub(purchaseAmount, Arith.add(finishAmount, unAmount)), purchaseData.getDouble(PurchaseEnum.BAD_AMOUNT.getAttr())));
                purchaseData.put(PurchaseEnum.RECEINE_PERCENT.getAttr(),Arith.div(Arith.add(finishAmount , unAmount),purchaseAmount));
                UpdateDataEntity contractUpdateEntity = ExplainUtil.getUpdateData(purchaseId, purchaseData, corpid);
                purchaseUpdateList.remove(oldPurchaseUpdateEntity);
                purchaseUpdateList.add(contractUpdateEntity);
                purchaseUpdateIdMap.put(purchaseId, contractUpdateEntity);
            } else {
                purchaseData.put(PurchaseEnum.FINISH_AMOUNT.getAttr(),Arith.add(finishAmount, unAmount));
                purchaseData.put(PurchaseEnum.UN_FINISH_AMOUNT.getAttr(),Arith.sub(purchaseAmount,Arith.sub(purchaseData.getDouble(PurchaseEnum.FINISH_AMOUNT.getAttr()), purchaseData.getDouble(PurchaseEnum.BAD_AMOUNT.getAttr()))));
                purchaseData.put(PurchaseEnum.RECEINE_PERCENT.getAttr(),Arith.div(Arith.add(finishAmount, unAmount),purchaseAmount));
                UpdateDataEntity contractUpdateEntity = ExplainUtil.getUpdateData(purchaseId, purchaseData, corpid);
                purchaseUpdateList.add(contractUpdateEntity);
                purchaseUpdateIdMap.put(purchaseId, contractUpdateEntity);
            }
        }
        if(!purchaseUpdateList.isEmpty()){
            payPlanModel.updateBatch(payPlanUpdateList,corpid);
        }
        Runnable runnable = () -> {
            try {
                if (!paySheetEntityExtList.isEmpty()) {
                    paySheetModel.insertBatch(paySheetEntityExtList);
                    for (PayPlanSheetEntityExt payPlanSheetEntityExt : paySheetEntityExtList) {
                        JSONObject data = payPlanSheetEntityExt.getData();
                        Long accountId = FastJsonHelper.getLongOrDefaultFromFormData(data, PaySheetEnum.FUND_ACCOUNT.getAttr(), 0L);
                        Double sheetAmount = getDoubleOrDefaultFromFormData(data, PaySheetEnum.AMOUNT.getAttr(), 0D);
                        //账户余额变动 付款取反
                        sheetAmount = Arith.mul(sheetAmount, -1);
                        fundAccountToAmountMap.merge(accountId, sheetAmount, Arith::add);
                        //流水表日志记录
                        FundAccountFlowEntity fundAccountFlowEntity = new FundAccountFlowEntity(corpid, DateTimeUtil.getInt(), payPlanSheetEntityExt.getCreatorId(), FundAccountFlowTypeEnum.PAY_SHEET.getCode(), payPlanSheetEntityExt.getId(), accountId, now, sheetAmount);
                        fundAccountFlowEntities.add(fundAccountFlowEntity);
                    }
                    if (fundAccountFlowEntities.size() > 0) {
                        fundAccountFlowModel.insertBatch(fundAccountFlowEntities);
                    }
                    if (fundAccountToAmountMap.size() > 0) {
                        fundAccountService.saveBatchByPaymentSheetOrPaySheet(fundAccountToAmountMap);
                    }
                    List<Long> purchaseIdIn = new ArrayList<>();
                    Map<Long, List<Long>> idAndContractIdMap = new HashMap<>(paySheetEntityExtList.size());
                    JSONObject customerData = paySheetEntityExtList.get(0).getData();
                    Long supplierId = FastJsonHelper.getLongOrDefaultFromFormData(customerData, PaySheetEnum.LINK_SUPPLIER.getAttr(), 0L);
                    for ( PayPlanSheetEntityExt paymentEntityExt : paySheetEntityExtList ) {
                        fundHelp.handleSheetIdAndContractIdMap(purchaseIdIn, idAndContractIdMap, paymentEntityExt, PaySheetEnum.LINK_PURCHASE.getAttr());
                    }
                    userTeamService.createPaySheetUser(corpid, supplierId, purchaseIdIn, idAndContractIdMap, SheetTypeEnum.WRITE_OFF, false);
                }
                if (!purchaseUpdateList.isEmpty()){
                    purchaseModel.updateBatch(purchaseUpdateList,corpid);
                }
            } catch (XbbException e) {
                LOG.error("设置已付款中更新合同或新增付款单报错", e);
            }

        };
        threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);

        // 设置回款已收款日志
        String userName = listBatchDTO.getLoginUserName();
        String nameStr = StringUtils.join(payPlanNoList, "，");
        if(paySheetEntityExtList.size() > 1){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_SET_PAY_SHEET), userName, XbbRefTypeEnum.PAY_PLAN.getName(), paySheetEntityExtList.size());
            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            InfoArrPojo infoArrPojo = new InfoArrPojo();
            infoArrPojo.setTitle(PaySheetEnum.PAY_PLAN_NO.getAttrName());
            infoArrPojo.setContent(nameStr);
            infoArrPojoList.add(infoArrPojo);
            mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.PayManage, OperateTypeEnum.SET,
                    "", "", memo, listBatchDTO.getHttpHeader());
        } else if (Objects.equals(paySheetEntityExtList.size(), 1)){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_SET_PAY_SHEET), userName, XbbRefTypeEnum.PAY_PLAN.getName(), nameStr);
            mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PayManage, OperateTypeEnum.SET,
                    paySheetEntityExtList.get(0).getDataId().toString(), nameStr, memo, listBatchDTO.getHttpHeader());
        }
        if ( CollectionsUtil.isNotEmpty(removePurchasePayPlanList) ) {
            List<String> errorDataList = new ArrayList<>();
            List<String> errorTypeList = new ArrayList<>();
            String errorDataMemo = String.format(MessageConstant.PURCHASE_OVER_AMOUNT, removePurchasePayPlanList.size());
            removePayPlanList.forEach(item->{
                errorDataList.add(item.getSerialNo());
            });
            errorTypeList.add(InvoiceErrorCodeEnum.API_ERROR_216048.getMsg());
            setPaymentBatchVO.setErrorDataList(errorDataList);
            setPaymentBatchVO.setErrorTypeList(errorTypeList);
            setPaymentBatchVO.setErrorDataMemo(errorDataMemo);
        }
        return setPaymentBatchVO;
    }

    @Override
    public BaseVO revert(ListBatchDTO listBatchDTO) throws XbbException {
        try {
         if (SaasMarkEnum.SAAS.getCode().equals(listBatchDTO.getSaasMark())) {
             Integer businessType = listBatchDTO.getBusinessType();
             String corpid = listBatchDTO.getCorpid();
             Integer saasMark = listBatchDTO.getSaasMark();
             XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
             SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
             BoolQueryBuilder boolQueryBuilder = boolQuery();
             boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(),listBatchDTO.getDataIdList()));
             IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, businessType, listBatchDTO.getSaasMark());
             boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
             SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
             PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, listBatchDTO.getDataIdList().size());
             sourceBuilder.query(boolQueryBuilder);
             searchRequest.source(sourceBuilder);
             XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
             Iterator<PaasFormDataEntityExt> iterator = esEntities.getContent().iterator();
             List<Long> dataIdList = new ArrayList<>();
             Map<Long, Long> customerUpdateTimeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
             List<String> names = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
             String nameAttr = CustomerManagementEnum.NAME.getAttr();
             if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                 nameAttr = ClueEnum.COMPANY_NAME.getAttr();
             }
             Long formId = 0L;
             while (iterator.hasNext()){
                 PaasFormDataEntityExt paasFormDataEsEntity = iterator.next();
                 if (paasFormDataEsEntity.getDel() != 1){
                     continue;
                 }
                 formId = paasFormDataEsEntity.getFormId();
                 dataIdList.add(paasFormDataEsEntity.getDataId());
                 customerUpdateTimeMap.put(paasFormDataEsEntity.getDataId(), paasFormDataEsEntity.getUpdateTime());
                 String name = FastJsonHelper.getStringOrDefaultFromFormData(paasFormDataEsEntity.getData(), nameAttr, "");
                 names.add(name);
             }
             if (Objects.isNull(listBatchDTO.getFormId())) {
                 listBatchDTO.setFormId(formId);
             }
             if (dataIdList.isEmpty()){
                 return new BaseVO();
             }
             //富文本还原单独处理
             richTextService.operateBatch(new FormRichTextBatchDTO(corpid, formId, businessType, saasMark, dataIdList, DelEnum.DELETE.getDel(), DelEnum.NORMAL.getDel()));
             switch (xbbRefTypeEnum){
                 case CUSTOMER_MANAGEMENT:
                     marketActivityForStaticHelp.deleteBatchMarketActivity(dataIdList, XbbRefTypeEnum.CUSTOMER_MANAGEMENT, corpid, DelEnum.NORMAL.getDel());
                     customerModel.restoreBatch(dataIdList, corpid, DelEnum.NORMAL.getDel());
                     proUpdateHelp.updateByIds(xbbRefTypeEnum.getCode(),corpid,dataIdList,CustomerManagementEnum.IS_PUBLIC.getAttr(),1);
                     // customerRestoreBatchDTO 主要是打日志用
                     CustomerRestoreBatchDTO customerRestoreBatchDTO = new CustomerRestoreBatchDTO();
                     BeanUtil.copyProperties(listBatchDTO, customerRestoreBatchDTO);
                     // 客户还原日志
                     OperateTypeEnum operateTypeEnum = OperateTypeEnum.REVERT_CANCEL;
                     String nameStr = StringUtils.join(names, "、");
                     String userName = customerRestoreBatchDTO.getLoginUserName();
                     String userId = customerRestoreBatchDTO.getUserId();
                     RevertLogDTO revertLogDTO = new RevertLogDTO(listBatchDTO,nameStr);
                     customerOperationLogHandle.revert(revertLogDTO);
                     // 客户动态日志
                     if (!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), listBatchDTO.getDistributorMark())) {
                         CustomerDynamicStrategy dynamicStrategy = dynamicStrategyFactory.getCustomerDynamicStrategy(ProjectLogEnum.CUSTOMER_RESTORE.getSubType());
                         dynamicStrategy.restore(DynamicRestoreDTO.initDynamicRestoreDTO(listBatchDTO, dataIdList));
                     }
                     // 还原相关联业务
                     restoreRalationBusiness(corpid, customerUpdateTimeMap, customerRestoreBatchDTO);
                     break;
                 case CLUE:
                     // clueRestoreBatchDTO 主要是打日志用
                     marketActivityForStaticHelp.deleteBatchMarketActivity(dataIdList, XbbRefTypeEnum.CLUE, corpid, DelEnum.NORMAL.getDel());
                     CustomerRestoreBatchDTO clueRestoreBatchDTO = new CustomerRestoreBatchDTO();
                     BeanUtil.copyProperties(listBatchDTO, clueRestoreBatchDTO);
                     String publicAttr = ClueEnum.IS_PUBLIC.getAttr();
                     clueModel.restoreBatch(dataIdList, corpid, DelEnum.NORMAL.getDel(), publicAttr);
                     // 还原线索跟进记录
                     customerCommunicateService.restoreBatch4Clue(corpid, customerUpdateTimeMap, clueRestoreBatchDTO);
                     // 还原日志
                     OperateTypeEnum operateTypem = OperateTypeEnum.REVERT_CANCEL;
                     String clueNameStr = StringUtils.join(names, "，");
                     String loginUserName = clueRestoreBatchDTO.getLoginUserName();
                     String loginUserId = clueRestoreBatchDTO.getUserId();
                     if(dataIdList.size() > 1){
                         String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_REVERT_FORM_DETAIL), loginUserName, operateTypem.getName(), dataIdList.size());
                         List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                         InfoArrPojo infoArrPojo = new InfoArrPojo();
                         infoArrPojo.setTitle(ClueEnum.COMPANY_NAME.getAttrName());
                         infoArrPojo.setContent(clueNameStr);
                         infoArrPojoList.add(infoArrPojo);
                         mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, loginUserId, loginUserName, OperateModuleTypeEnum.CLUE, operateTypem,
                                 "", "", memo, clueRestoreBatchDTO.getHttpHeader());
                     } else if(Objects.equals(dataIdList.size(), 1)){
                         String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ARCHIVE_FORM_DATA), loginUserName, operateTypem.getName(), clueNameStr);
                         mongoLogHelp.buildLog(corpid, loginUserId, loginUserName, OperateModuleTypeEnum.CLUE, operateTypem,
                                 dataIdList.get(0).toString(), clueNameStr, memo, clueRestoreBatchDTO.getHttpHeader());
                     }
                     break;
                 default:
                         break;
             }
         } else {
             FormDataRestoreDTO formDataRestoreDTO = new FormDataRestoreDTO();
             PaasFormDataEntityExt paasFormDataEntity = paasFormDataModel.getByKey(listBatchDTO.getDataIdList().get(0), listBatchDTO.getCorpid());
             if (Objects.isNull(paasFormDataEntity)){
                 throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018);
             }
             BeanUtil.copyProperties(listBatchDTO, formDataRestoreDTO);
             formDataRestoreDTO.setFormId(paasFormDataEntity.getFormId());
             paasFormDataService.restore(formDataRestoreDTO);
         }
        } catch (Exception e) {
            LOG.error("还原失败： 失败原因:", e);
        }
        return new BaseVO();
    }

    @Override
    public TeamBatchVO customerGrab(ListBatchDTO listBatchDTO) throws XbbException {
        TeamBatchVO teamBatchVO;
        Integer businessType = listBatchDTO.getBusinessType();
        if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
            TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), null, DistributorMarkEnum.OTHER.getCode());
            teamBatchVO = grabCustomer(listBatchDTO);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
            TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CLUE.getCode(), null, DistributorMarkEnum.OTHER.getCode());
            teamBatchVO = grabClue(listBatchDTO);
        } else {
            throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        return teamBatchVO;
    }

    private TeamBatchVO grabCustomer(ListBatchDTO listBatchDTO) throws XbbException {
        LOG.info("公海池捞取开始long："+DateUtil.getLong());
        // 判断捞取权限
        if (!listBatchDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.CUSTOMER_GAIN.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100017);
        }
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        //List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();
        String corpid = listBatchDTO.getCorpid();
        List<Long> dataIdList = listBatchDTO.getDataIdList();
        Integer dataIdSize = dataIdList.size();
        Long formId = listBatchDTO.getFormId();
        if (Objects.isNull(formId) && dataIdSize > 0) {
            CustomerEntityExt customerEntityExt = customerModel.getByKey(dataIdList.get(0), corpid);
            formId = customerEntityExt.getFormId();
        }
//        customerOperateLocking(listBatchDTO.getUserId(),corpid,RedisPrefixConstant.CUSTOMER_GRAB);
        List<Long> lackCustomerList = customerDataLocking(dataIdList,corpid);
        String userId = listBatchDTO.getUserId();
        UserEntity userEntity = userModel.getByKey(userId,corpid);
        if (Objects.isNull(userEntity)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100065);
        }
        String userName = userEntity.getName();

        // 非公海客户
        Map<Long, String> noPublicMap = new HashMap<>();
        /*List<String> notPublics = new ArrayList<>();
        List<Long> notPublicIds = new ArrayList<>();*/
        //只存捞取成功的客户id
        List<Long> customerIdList = new ArrayList<>();
        Map<Long,String> customerNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<PaasFormDataEntityExt> publicList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        TeamAfterVerifyDTO teamAfterVerifyDTO = null;
        if (!dataIdList.isEmpty()) {
            try {
                IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

                SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
                boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIdList));
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, customerIndex.getType()));
                sourceBuilder.query(boolQueryBuilder);
                List<String> fieldList = new ArrayList<>();
                fieldList.add(FieldTypeEnum.DATAID.getAlias());
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.NAME));
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.IS_PUBLIC));
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.IMPORTANT_DEGREE));
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.TYPE));
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.LABEL));
                fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.PUBLIC_GROUP));
                String[] strings = new String[fieldList.size()];
                sourceBuilder.fetchSource(fieldList.toArray(strings),null);
                SearchRequest searchRequest = new SearchRequest(customerIndex.getIndex());
                PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, dataIdList.size());
                searchRequest.source(sourceBuilder);
                XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
                if (esEntities == null) {
                    return teamBatchVO;
                }
                List<PaasFormDataEntityExt> list = esEntities.getContent();
                Map<Long, PaasFormDataEntityExt> entityExtMap = new HashMap<>(list.size());
                list.forEach(item -> entityExtMap.put(item.getDataId(), item));
                // 公海池规则校验在CustomerTeamStrategy.save()做
                //errorMap = canGainCustomer(corpid, dataIdList, userEntity, entityExtMap);

                for (Long customerId : dataIdList) {
                    PaasFormDataEntityExt entity = entityExtMap.get(customerId);
                    String customerName = FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), CustomerManagementEnum.NAME.getAttr(), "");
                    Integer isPublic = getIntegerOrDefaultFromFormData(entity.getData(), CustomerManagementEnum.IS_PUBLIC.getAttr(), 0);
                    if (Objects.equals(isPublic, 0)) {
                        // 非公海客户跳过
                        noPublicMap.put(customerId, customerName);
                        /*notPublics.add(customerName);
                        notPublicIds.add(customerId);*/
                        continue;
                    }
                    //捞取频次在CustomerTeamStrategy.afterSave()做
                    //customerRuleService.updateGainRateToRedis(corpid, userEntity);
                    customerIdList.add(customerId);
//                    customerNameList.add(customerName);
                    customerNameMap.put(customerId, customerName);
                    publicList.add(entity);
                }
               /* if (!notPublicIds.isEmpty()) {
                    //removeCustomerDataLock(notPublicIds, corpid);
                }*/
            } catch (Exception e) {
                //removeCustomerDataLock(dataIdList, corpid);
            }
            if (!customerIdList.isEmpty()) {
                //公海池校验
                TeamUpdateMidPOJO teamUpdateMidPOJO = new TeamUpdateMidPOJO(corpid,customerIdList,formId,SaasMarkEnum.SAAS.getCode(),listBatchDTO.getBusinessType(),
                        DistributorMarkEnum.OTHER.getCode(), new HashSet<>(Collections.singletonList(userId)),null,null,null,listBatchDTO.getLoginUser(),true,false);
                teamUpdateMidPOJO.setOprateTag(UserTeamOperateTagEnum.GET_CUSTOMER.getOperateTag());
                teamAfterVerifyDTO = teamDataHelp.publicVerify(teamUpdateMidPOJO, false);

                //获取实际要捞取的客户id
                Map<String, Set<String>> addMainUserMap = teamAfterVerifyDTO.getAddMainUserMap();
                customerIdList = addMainUserMap.keySet().stream().map(Long::valueOf).collect(Collectors.toList());
                //更新一下捞取频率
                List<String> idList = addMainUserMap.entrySet().stream()
                        .filter(v -> Objects.nonNull(v.getValue()))
                        .flatMap(v -> v.getValue().stream())
                        .distinct().collect(Collectors.toList());
                List<UserEntity> users = userModel.findEntitysByUserIds(idList, corpid);
                for (Long data: customerIdList) {
                    Set<String> addMainUsers = addMainUserMap.getOrDefault(String.valueOf(data), new HashSet<>());
                    List<UserEntity> collect = users.stream().filter(v -> addMainUsers.contains(v.getUserId())).collect(Collectors.toList());
                    for (UserEntity userEntitySen : collect) {
                        customerRuleService.updateGainRateToRedis(corpid,userEntitySen);
                    }
                }

                //更新数据
                if (CollectionsUtil.isNotEmpty(customerIdList)){
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put(CustomerManagementEnum.DISTRIBUTION_DATE.getAttr(), DateTimeUtil.getInt());
                    jsonObject.put(CustomerManagementEnum.IS_PUBLIC.getAttr(), PublicEnum.NON_PUBLIC.getCode());
                    jsonObject.put(CustomerManagementEnum.IS_ARCHIVED.getAttr(), ArchivedEnum.UN_ARCHIVED.getCode());
                    proUpdateHelp.updateByIds(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), corpid, customerIdList, jsonObject);
                }
                LOG.info("公海池捞取结束long："+DateUtil.getLong());
                TeamAfterVerifyDTO finalTeamAfterVerifyDTO = teamAfterVerifyDTO;
                List<Long> finalCustomerIdList = customerIdList;
                Runnable runnable = () -> {
                    try {

                        if(Objects.isNull(finalTeamAfterVerifyDTO)){
                            return;
                        }
                        //更新团队
                        teamDataHelp.batchUpdateTeam(finalTeamAfterVerifyDTO);
                        if(CollectionsUtil.isEmpty(finalCustomerIdList)){
                            return;
                        }
                        //只要线索除了公海池，移除转移公海池的标签
                        tagLinkModel.deleteTagByTagTypeAndRefIdIn(corpid, TagTypeEnum.TRANSFER_CUSTOMER_RULE.getCode(), finalCustomerIdList);
                        // 添加动态
                        if(!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(),listBatchDTO.getDistributorMark())) {
                            CustomerDynamicStrategy customerDynamicStrategy = dynamicStrategyFactory.getCustomerDynamicStrategy(ProjectLogEnum.CUSTOMER_GRAB.getSubType());
                            customerDynamicStrategy.grap(new DynamicGrapDTO(listBatchDTO, finalCustomerIdList, userEntity));
                        }
                    } catch (XbbException e) {
                        LOG.error("customerGrab error:", e);
                    }
                };
                threadPoolBeanConfig.listBatchThreadPool().execute(runnable);
                //捞取公海池日志
                if(CollectionsUtil.isNotEmpty(finalCustomerIdList)) {
                    List<String> customerNameList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for (Long finalCustomerId : finalCustomerIdList) {
                        String customerName = customerNameMap.get(finalCustomerId);
                        customerNameList.add(customerName);
                    }
                    String logMemo = StringUtils.join(customerNameList, "、");
                    CustomerGrabLogDTO customerGrabLogDTO = new CustomerGrabLogDTO(listBatchDTO,logMemo);
                    customerOperationLogHandle.grab(customerGrabLogDTO);
                }
            }
        }

        List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();

        if(!Objects.isNull(teamAfterVerifyDTO)){
            teamBatchPojos = teamAfterVerifyDTO.getTeamBatchPojos();
        }

        packageDistributionError(listBatchDTO.getBusinessType(), listBatchDTO.getSaasMark(), teamBatchPojos, noPublicMap, lackCustomerList,
                corpid, teamBatchVO, dataIdSize, UserTeamOperateTagEnum.GET_CUSTOMER.getName());
        /*if (!notPublics.isEmpty()) {
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.NOT_PUBLIC));
            commonHelp.mergeFailMsg(notPublics, dataIdSize, teamBatchPojo, SaasBatchEnum.GET_CUSTOMER.getValue(), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }

        if (!lackCustomerList.isEmpty()) {
            TeamBatchPojo teamBatchPojo = lackError(lackCustomerList, dataIdSize, corpid, teamBatchVO, SaasBatchEnum.GET_CUSTOMER.getValue());
            teamBatchPojos.add(teamBatchPojo);
        }
        //异常处理
        if(!teamBatchPojos.isEmpty()){
            if(Objects.isNull(teamAfterVerifyDTO) || MapUtils.isEmpty(teamAfterVerifyDTO.getAddMainUserMap())){
                //所有都捞取失败
                teamBatchVO.setResultMsg(ListBatchResultEnum.OPERATE_FAIL.getMsg());
                teamBatchVO.setResultType(ListBatchResultEnum.OPERATE_FAIL.getAlias());
            }
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
            return teamBatchVO;
        }*/


        return teamBatchVO;
    }

    private TeamBatchVO grabClue(ListBatchDTO listBatchDTO) throws XbbException {
        // 判断捞取权限
        if (!listBatchDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.CLUE_GAIN.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100017);
        }
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        //List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();
        String corpid = listBatchDTO.getCorpid();
        Integer businessType = listBatchDTO.getBusinessType();
        List<Long> dataIdList = listBatchDTO.getDataIdList();
        Integer dataIdSize = dataIdList.size();
        Long formId = listBatchDTO.getFormId();
        if (Objects.isNull(formId) && dataIdSize > 0) {
            ClueEntityExt clueEntityExt = clueModel.getByKey(dataIdList.get(0), corpid);
            formId = clueEntityExt.getFormId();
        }
        List<Long> lackClueList = clueDataLocking(dataIdList,corpid);
        Set<Long> lockClues = clueAutoAssignmentLocking(dataIdList,corpid);
        String userId = listBatchDTO.getUserId();
        UserEntity userEntity = userModel.getByKey(userId,corpid);
        if (Objects.isNull(userEntity)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100065);
        }
        String userName = userEntity.getName();

        // 非公海线索
        Map<Long, String> noPublicMap = new HashMap<>();
        //只存捞取成功的线索id
        List<Long> clueIdList = new ArrayList<>();
        List<String> clueNameList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<PaasFormDataEntityExt> publicList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        TeamAfterVerifyDTO teamAfterVerifyDTO = null;
        List<TeamBatchPojo> groupTeamBatchPojos = null;
        if (!dataIdList.isEmpty()) {
            try {
                SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
                boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIdList));
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CLUE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                List<String> fieldList = new ArrayList<>();
                fieldList.add(FieldTypeEnum.DATAID.getAlias());
                fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.COMPANY_NAME));
                fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.IS_PUBLIC));
                fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.CLUE_STATUS));
                fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.LABEL));
                String[] strings = new String[fieldList.size()];
                sourceBuilder.fetchSource(fieldList.toArray(strings),null);

                SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CLUE.getIndex());
                PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, dataIdList.size());
                searchRequest.source(sourceBuilder);
                XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
                if (esEntities == null) {
                    return teamBatchVO;
                }
                List<PaasFormDataEntityExt> list = esEntities.getContent();
                Map<Long, PaasFormDataEntityExt> entityExtMap = new HashMap<>(list.size());
                list.forEach(item -> entityExtMap.put(item.getDataId(), item));
                // 公海池规则和更新捞取频率在策略的save和afterSave实现
//                errorMap = canGainClue(corpid, dataIdList, userEntity, entityExtMap);
                for (Long clueId : dataIdList) {
                    PaasFormDataEntityExt entity = entityExtMap.get(clueId);
                    String clueName = FastJsonHelper.getStringOrDefaultFromFormData(entity.getData(), ClueEnum.COMPANY_NAME.getAttr(), "");
                    Integer isPublic = getIntegerOrDefaultFromFormData(entity.getData(), ClueEnum.IS_PUBLIC.getAttr(), 0);
                    if (Objects.equals(isPublic, 0)) {
                        // 非公海线索跳过
                        noPublicMap.put(clueId, clueName);
                        continue;
                    }
                    // 线索公海池规则更新捞取频率,在clueTeamStrategy.afterSave()
                    //clueRuleService.updateGainRateToRedis(corpid, userEntity);
                    clueIdList.add(clueId);
                    clueNameList.add(clueName);
                    publicList.add(entity);
                }
            } catch (Exception e) {
            }
            if (!clueIdList.isEmpty()) {
                //公海池校验
                //线索捞取，下游客户团队不继承，设置isInheritance为true跳过下游业务
                TeamUpdateMidPOJO teamUpdateMidPOJO = new TeamUpdateMidPOJO(corpid,clueIdList,formId,SaasMarkEnum.SAAS.getCode(),listBatchDTO.getBusinessType(),
                        DistributorMarkEnum.OTHER.getCode(), new HashSet<>(Collections.singletonList(userId)),null,null,null,listBatchDTO.getLoginUser(), true, false);
                teamUpdateMidPOJO.setOprateTag(UserTeamOperateTagEnum.GET_CUSTOMER.getOperateTag());
                teamAfterVerifyDTO = teamDataHelp.publicVerify(teamUpdateMidPOJO, false);
                //获取实际要捞取的线索id
                Map<String, Set<String>> addMainUserMap = teamAfterVerifyDTO.getAddMainUserMap();
                clueIdList = teamAfterVerifyDTO.getAddMainUserMap().keySet().stream().map(Long::valueOf).collect(Collectors.toList());
                //更新一下捞取频率
                List<String> idList = addMainUserMap.entrySet().stream()
                        .filter(v -> Objects.nonNull(v.getValue()))
                        .flatMap(v -> v.getValue().stream())
                        .distinct().collect(Collectors.toList());
                List<UserEntity> users = userModel.findEntitysByUserIds(idList, corpid);
                for (Long data: clueIdList) {
                    Set<String> addMainUsers = addMainUserMap.getOrDefault(String.valueOf(data), new HashSet<>());
                    List<UserEntity> collect = users.stream().filter(v -> addMainUsers.contains(v.getUserId())).collect(Collectors.toList());
                    for (UserEntity userEntitySen : collect) {
                        clueRuleService.updateGainRateToRedis(corpid,userEntitySen);
                    }
                }
                //更新数据
                if (CollectionsUtil.isNotEmpty(clueIdList)) {
                    Map<String, Object> updateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    updateMap.put(ClueEnum.DISTRIBUTION_DATE.getAttr(), DateTimeUtil.getInt());
                    updateMap.put(ClueEnum.IS_PUBLIC.getAttr(), PublicEnum.NON_PUBLIC.getCode());
                    updateMap.put(ClueEnum.IS_ARCHIVED.getAttr(), ArchivedEnum.UN_ARCHIVED.getCode());
                    clueModel.updateBatchNoSub(corpid, clueIdList, updateMap, WriteRequest.RefreshPolicy.NONE);
                }

                TeamAfterVerifyDTO finalTeamAfterVerifyDTO = teamAfterVerifyDTO;
                List<Long> finalClueIdList = clueIdList;
                Runnable runnable = () -> {
                    try {
                        if(Objects.isNull(finalTeamAfterVerifyDTO)){
                            return;
                        }
                        //更新团队
                        teamDataHelp.batchUpdateTeam(finalTeamAfterVerifyDTO);

                        if(CollectionUtils.isEmpty(finalClueIdList)){
                            return;
                        }
                        //只要线索除了公海池，移除转移公海池的标签
                        tagLinkModel.deleteTagByTagTypeAndRefIdIn(corpid, TagTypeEnum.TRANSFER_CLUE_RULE.getCode(), finalClueIdList);

                        //捞取公海池日志
                        String logMemo = StringUtils.join(clueNameList, "，");
                        if (clueNameList.size() > 1) {
                            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_GRAB_CLUE), userName, XbbRefTypeEnum.CLUE.getName(), clueNameList.size());
                            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                            InfoArrPojo infoArrPojo = new InfoArrPojo();
                            infoArrPojo.setTitle(ClueEnum.COMPANY_NAME.getAttrName());
                            infoArrPojo.setContent(logMemo);
                            infoArrPojoList.add(infoArrPojo);
                            mongoLogHelp.buildLog4InfoArrWithoutAsync(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.CLUE, OperateTypeEnum.SNATCH_CLUE_FROM_PUBLIC,
                                    "", "", memo, listBatchDTO.getHttpHeader());
                        } else if (Objects.equals(clueNameList.size(), 1)) {
                            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_GRAB_CLUE), userName, XbbRefTypeEnum.CLUE.getName(), logMemo);
                            mongoLogHelp.buildLogWithoutAsync(corpid, userId, userName, OperateModuleTypeEnum.CLUE, OperateTypeEnum.SNATCH_CLUE_FROM_PUBLIC,
                                    finalClueIdList.get(0).toString(), logMemo, memo, listBatchDTO.getHttpHeader());
                        }
                    } catch (XbbException e) {
                        LOG.error("grabClue error:", e);
                    }
                };
                threadPoolBeanConfig.listBatchThreadPool().execute(runnable);

            }
        }
        List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();
        if(!Objects.isNull(teamAfterVerifyDTO)){
            teamBatchPojos = teamAfterVerifyDTO.getTeamBatchPojos();
        }
        packageDistributionError(listBatchDTO.getBusinessType(), listBatchDTO.getSaasMark(), teamBatchPojos, noPublicMap, lackClueList,
                corpid, teamBatchVO, dataIdSize, UserTeamOperateTagEnum.GET_CUSTOMER.getName());
        /*
        if(!Objects.isNull(teamAfterVerifyDTO)){
            teamBatchPojos = teamAfterVerifyDTO.getTeamBatchPojos();
        }
        if (!notPublics.isEmpty()) {
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.NOT_PUBLIC_CLUE));
            commonHelp.mergeFailMsg(notPublics, dataIdSize, teamBatchPojo, SaasBatchEnum.GET_CUSTOMER.getValue(), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);
        }
        if (!lackClueList.isEmpty()) {
            TeamBatchPojo teamBatchPojo = lackClueError(lackClueList, dataIdSize, corpid, teamBatchVO, SaasBatchEnum.GET_CUSTOMER.getValue());
            teamBatchPojos.add(teamBatchPojo);
        }
        if (!lockClues.isEmpty()) {
            TeamBatchPojo teamBatchPojo = lockClueError(lockClues, dataIdSize, corpid, teamBatchVO, SaasBatchEnum.GET_CUSTOMER.getValue());
            teamBatchPojos.add(teamBatchPojo);
        }
        //异常处理
        if(!teamBatchPojos.isEmpty()){
            if(MapUtils.isEmpty(teamAfterVerifyDTO.getAddMainUserMap())){
                //所有都捞取失败
                teamBatchVO.setResultMsg(ListBatchResultEnum.OPERATE_FAIL.getMsg());
                teamBatchVO.setResultType(ListBatchResultEnum.OPERATE_FAIL.getAlias());
            }
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
            return teamBatchVO;
        }*/


        return teamBatchVO;
    }

    /**
     * 获取跟进提醒
     *
     * @param remindDTO 入参
     * @return 是否成功
     * @throws XbbException 异常
     */
    @Override
    public RemindVO getRemind(RemindDTO remindDTO) throws XbbException {
        RemindVO remindVO = new RemindVO();
        List<Long> dataIdList = remindDTO.getDataIdList();
        Integer businessType = remindDTO.getBusinessType();
        //塞入查询提醒的基础条件
        Map<String, Object> param = pushModel.pushNotifyParam(dataIdList, remindDTO.getCorpid(), businessType, DateUtil.getInt(), null);
        //再塞入其它需要的条件：排序、查询数量
        param.put("start", BasicConstant.ZERO);
        param.put("pageNum", 3);
        param.put("orderByStr", "push_time asc");

        JSONArray resultList = new JSONArray();
        List<PushEntity> list = pushModel.findEntitys(param);
        for(PushEntity entity : list){
            String pushTime = DateTimeUtil.getStringEpochSecond(entity.getPushTime(),DateUtil.SDFYMDHM);
            Long id = entity.getId();
            String msg = entity.getMsg();
            OA oa = JSONObject.parseObject(msg, OA.class);
            if (Objects.isNull(oa)) {
                oa = new OA();
            }
            OA.Body body = oa.getBody() == null ? new OA.Body() : oa.getBody();
            JSONObject pushObj = new JSONObject();
            pushObj.put("id", id);
            pushObj.put("pushTime", pushTime);
            pushObj.put("title", body.getTitle());
            pushObj.put("content", body.getContent());
            resultList.add(pushObj);
        }
        remindVO.setBusinessType(XbbRefTypeEnum.PUSH_NOTIFY.getCode());
        remindVO.setDataIdList(dataIdList);
        remindVO.setResultList(resultList);
        return remindVO;
    }

    /**
     * 信用账户冻结/解冻
     * @param creditFreezeDTO
     * @return
     * @author xingxing.xiao
     */
    @Override
    public BaseVO creditFreeze(CreditFreezeDTO creditFreezeDTO) throws XbbException {
        String corpid = creditFreezeDTO.getCorpid();
        Integer businessType = creditFreezeDTO.getBusinessType();
        Integer freeze = creditFreezeDTO.getFreeze();
        UserVO loginUser = creditFreezeDTO.getLoginUser();
        if (!loginUser.getPermSet().contains(ProPermissionAliasEnum.CREDIT_LIMIT_FREEZE.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CREDIT_LIMIT_FREEZE.getMemo()));
        }
        List<Long> dataIdList = creditFreezeDTO.getDataIdList();
        if (dataIdList.size() > 0) {
            if (Objects.equals(freeze, 0)) {
                // 临时额度和固定额度审批中有数据时不能冻结
                Map<Integer, Long> formMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                params.put(ParameterConstant.COLUMNS, "id, business_type");
                params.put(ParameterConstant.CORPID, corpid);
                params.put("businessTypeList", Arrays.asList(XbbRefTypeEnum.CREDIT_TEMPORARY_LIMIT.getCode(), XbbRefTypeEnum.CREDIT_FIXED_LIMIT.getCode()));
                params.put("distributorMark", DistributorMarkEnum.DISTRIBUTOR.getCode());
                params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
                List<PaasFormEntity> formEntities = paasFormModel.findEntity(params);
                formEntities.forEach(item -> formMap.put(item.getBusinessType(), item.getId()));
                List<Long> creditDistributorIdIn = new ArrayList<>();
                dataIdList.forEach(item -> creditDistributorIdIn.add(item));
                params.clear();
                params.put(ParameterConstant.CORPID, corpid);
                Long temporaryFormId = formMap.get(XbbRefTypeEnum.CREDIT_TEMPORARY_LIMIT.getCode());
                params.put("formId", temporaryFormId);
                params.put("creditTemporaryIdIn", creditDistributorIdIn);
                params.put("flowStatusIn", Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(), FlowStatusEnum.IN_APPROVAL.getType()));
                params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
                Integer temporaryCount = paasProcessDataModel.getEntitysCount(params);
                if (temporaryCount > 0) {
                    throw new XbbException(CreditManagement.API_ERROR_253011, String.format(I18nMessageUtil.getMessage(CreditManagement.API_ERROR_253011.getMsg()), XbbRefTypeEnum.CREDIT_TEMPORARY_LIMIT.getName()));
                }
                params.clear();
                params.put(ParameterConstant.CORPID, corpid);
                Long fixedFormId = formMap.get(XbbRefTypeEnum.CREDIT_FIXED_LIMIT.getCode());
                params.put("formId", fixedFormId);
                params.put("creditFixedIdIn", creditDistributorIdIn);
                params.put("flowStatusIn", Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(), FlowStatusEnum.IN_APPROVAL.getType()));
                params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
                Integer fixedCount = paasProcessDataModel.getEntitysCount(params);
                if (fixedCount > 0) {
                    throw new XbbException(CreditManagement.API_ERROR_253011, String.format(I18nMessageUtil.getMessage(CreditManagement.API_ERROR_253011.getMsg()), XbbRefTypeEnum.CREDIT_FIXED_LIMIT.getName()));
                }
            }

            proUpdateHelp.updateByIds(businessType, corpid, dataIdList, CreditLimitEnum.STATUS.getAttr(), freeze);
        }
        return new BaseVO();
    }

    /**
     * 临时额度撤销/重新生效
     * @param creditRevokeDTO
     * @author xingxing.xiao
     */
    @Override
    public BaseVO creditRevoke(CreditRevokeDTO creditRevokeDTO) throws XbbException {
        String corpid = creditRevokeDTO.getCorpid();
        Integer businessType = creditRevokeDTO.getBusinessType();
        Integer revoke = creditRevokeDTO.getRevoke();
        UserVO loginUser = creditRevokeDTO.getLoginUser();
        if (!loginUser.getPermSet().contains(ProPermissionAliasEnum.CREDIT_TEMPORARY_LIMIT_REVOKE.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CREDIT_TEMPORARY_LIMIT_REVOKE.getMemo()));
        }
        List<Long> dataIdList = creditRevokeDTO.getDataIdList();
        if (dataIdList.size() > 0) {
            proUpdateHelp.updateByIds(businessType, corpid, dataIdList, CreditTemporaryLimitEnum.APPLY_STATUS.getAttr(), revoke);
        }
        return new BaseVO();
    }

    @Transactional(rollbackFor = XbbException.class)
    @Override
    public BaseVO deleteRemind(DelRemindDTO deleteRemind) throws XbbException {
        Integer dataId = deleteRemind.getDataId().intValue();
        String corpid = deleteRemind.getCorpid();
        //校验
        checkDeleteInfo(dataId,corpid);
        //删除
        deletePushInfo(dataId,corpid);
        //操作日志
        operationLogHelp.deletePushNotifyLog(deleteRemind);
        PushNotifyDynamicStrategy pushNotifyDynamicStrategy = dynamicStrategyFactory.getPushNotifyDynamicStrategy();
        DynamicPushNotifyDeleteDTO dynamicPushNotifyDeleteDTO = new DynamicPushNotifyDeleteDTO();
        dynamicPushNotifyDeleteDTO.setDeleteRemind(deleteRemind);
        pushNotifyDynamicStrategy.delete(dynamicPushNotifyDeleteDTO);
        return new BaseVO();
    }

    private void checkDeleteInfo(Integer dataId , String corpid) throws XbbException {
        PushEntity pushEntity =  pushModel.getByKey(dataId,corpid);
        if(Objects.isNull(pushEntity)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100019, "提醒数据不存在，无法删除和编辑");
        }
        long now = DateTimeUtil.getInt();
        if(pushEntity.getIsPush() == 1){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100019, "提醒已推送，无法删除和编辑");
        }
        if(now > pushEntity.getPushTime()){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100019, "提醒已过期，无法删除和编辑");
        }
    }

    private void deletePushInfo(Integer dataId , String corpid){
        try {
            //删除主表信息
            pushModel.deleteByKey(dataId,corpid);
            //删除关联表信息(一对一的关联)
            pushLinkModel.deleteByPushIdIn(Arrays.asList(dataId.longValue()),corpid);
        }catch (Exception e){
            LOG.error("删除提醒发生DB异常,数据主键-{}-",dataId);
        }
    }
    @Transactional(rollbackFor = XbbException.class)
    @Override
    public BaseVO updateRemind(UpdateRemindDTO updateRemindDTO) throws XbbException {
        UpdateRemindDTO oldUpdateRemindDTO = (UpdateRemindDTO)CloneUtil.deepClone(updateRemindDTO);
        Integer pushId = updateRemindDTO.getDataId().intValue();
        String corpid = updateRemindDTO.getCorpid();
        //删除旧的提醒
        deletePushInfo(pushId,corpid);
        //插入新的提醒
        FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
        BeanUtil.copyProperties(updateRemindDTO,formDataAddDTO);
        formDataAddDTO.setIsBatch(-1);
        // 这边给个-1  不然下面是走新增逻辑会有新增日志
        BaseVO baseVO = pushNotify(formDataAddDTO);
        PushNotifyLogHandle pushNotufyLogHandle = operationLogFactory.getPushNotufyLogHandle(SaasMarkEnum.SAAS.getCode(),
                XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
        pushNotufyLogHandle.edit(oldUpdateRemindDTO);
        return baseVO;
    }

    @Override
    public BaseVO changeStatus(StatusChangeDTO statusChangeDTO) throws XbbException {
        String corpid = statusChangeDTO.getCorpid();
        List<Long> idIn = statusChangeDTO.getDataIdList();
        Integer status = statusChangeDTO.getStatus();
        List<DistributorAccountEntity> distributorAccountEntityList = distributorAccountModel.getByIdIn(corpid, idIn);
        if (Objects.equals(status, 1)) {
            // 需要校验启用中的手机号是否重复
            List<Long> distributorIdList = new ArrayList<>();
            // fix 37285
            Set<String> phoneSet = new HashSet<>();
            for (DistributorAccountEntity item : distributorAccountEntityList) {
                boolean isRepeat = phoneSet.contains(item.getPhone());
                phoneSet.add(item.getPhone());
                if (Objects.equals(item.getEnable(), 0)) {
                    boolean repeat = distributorAccountModel.phoneRepeat(corpid, item.getPhone(), item.getId());
                    if (repeat || isRepeat) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006.getCode(), ErrorMessageConstant.MOBILE_IS_REPEAT);
                    }
                }
                distributorIdList.add(item.getDistributorId());
            }
            boolean isOverPackage = distributorAccountService.isOverPackage(corpid, distributorIdList);
            if (isOverPackage) {
                throw new  XbbException(SystemErrorCodeEnum.API_ERROR_100074);
            }
        }
        distributorAccountEntityList.forEach(item -> {
            item.setEnable(status);
            if (Objects.equals(status, 0)) {
                paasRedisHelper.removeHashValue(RedisPrefixConstant.DISTRIBUTOR_XBB_ACCESS_TOKEN, item.getCorpid(), item.getId().toString());
            }
        });
        distributorAccountModel.updateBatch(distributorAccountEntityList);

        return new BaseVO();
    }

    /**
     * 隔离模式下批量新增协同人
     *
     * @param isolationAddCoUserDTO
     * @return
     * @throws XbbException
     */
    @Override
    public TeamBatchVO addCoUserForIsolation(IsolationAddCoUserDTO isolationAddCoUserDTO) throws XbbException {
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        String teamUserId = isolationAddCoUserDTO.getMainUserId();
        if(StringUtil.isEmpty(teamUserId)){
            //隔离模式批量新增协同人，负责人id为必填
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsg(I18nMessageUtil.getMessage(TeamMembersConstant.CREATE_CO_USER_FAIL_MESSAGE));
            teamBatchPojo.setFailMsgReason(UserTeamErrorCodeEnum.API_ERROR_271031.getMsg());
            teamBatchVO.setTeamBatchPojos(Collections.singletonList(teamBatchPojo));
            teamBatchVO.setResultType(ListBatchResultEnum.OPERATE_FAIL.getAlias());
            teamBatchVO.setResultMsg(ListBatchResultEnum.OPERATE_FAIL.getMsg());
            return teamBatchVO;
        }
        int size = isolationAddCoUserDTO.getDataIdList().size();
        String corpid = isolationAddCoUserDTO.getCorpid();
        List<Long> dataIdList = isolationAddCoUserDTO.getDataIdList();
        Integer businessType = isolationAddCoUserDTO.getBusinessType();
        Long formId = isolationAddCoUserDTO.getFormId();
        UserVO loginUser = isolationAddCoUserDTO.getLoginUser();
        //校验数据权限
        List<TeamBatchPojo> teamBatchPojos = checkDataPermission4Isolation(dataIdList, businessType, formId, corpid, loginUser, UserTeamOperateTagEnum.ADD_COUSER);
        // 批量的数据锁
        String redisPrefix = teamDataHelp.getRedisPrefix(isolationAddCoUserDTO.getSaasMark(), isolationAddCoUserDTO.getBusinessType());
        List<Long> lackIdList = dataLocking(isolationAddCoUserDTO.getDataIdList(), isolationAddCoUserDTO.getCorpid(), redisPrefix);


        List<TeamBatchPojo> batchPojo4Approval = teamHelp.checkDataIsApproval(isolationAddCoUserDTO.getDataIdList(), isolationAddCoUserDTO.getCorpid(), isolationAddCoUserDTO.getFormId(), isolationAddCoUserDTO.getSaasMark(), isolationAddCoUserDTO.getBusinessType(), UserTeamOperateTagEnum.ADD_COUSER);
        if(CollectionsUtil.isNotEmpty(batchPojo4Approval)){
            teamBatchPojos.addAll(batchPojo4Approval);
        }
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(isolationAddCoUserDTO, teamVerifyDTO);
        teamVerifyDTO.setTeamUserId(teamUserId);
        teamVerifyDTO.setNewAddCoUserList(new HashSet<>(isolationAddCoUserDTO.getUserIdList()));
        teamVerifyDTO.setDataId(isolationAddCoUserDTO.getDataIdList());
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setBatchTag(Constant.ONE);
        teamVerifyDTO.setLoginUser(isolationAddCoUserDTO.getLoginUser());

        teamBatchPojos.addAll(teamDataHelp.save(teamVerifyDTO));

        // 封装批量因为被加锁不能操作的报错处理
        if (CollectionsUtil.isNotEmpty(lackIdList)) {
            Map<Long, String> nameOrSeriNoMap = new HashMap<>();
            userTeamHelp.getEntityMap(teamVerifyDTO.getBusinessType(), lackIdList, teamVerifyDTO.getCorpid(), nameOrSeriNoMap, teamVerifyDTO.getSaasMark());
            List<String> lackName = new ArrayList<>(lackIdList.size());
            for (Long id : lackIdList) {
                lackName.add(nameOrSeriNoMap.getOrDefault(id, ""));
            }
            commonHelp.batchSameErrorPackage(lackName, UserTeamOperateTagEnum.ADD_COUSER.getName(),
                    UserTeamErrorCodeEnum.API_ERROR_271020.getCode(), UserTeamErrorCodeEnum.API_ERROR_271020.getMsg(), teamBatchPojos);
        }

        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
            commonHelp.batchFailMsg(teamBatchPojos, size, teamBatchVO);
        }

        return teamBatchVO;
    }

    /**
     * 隔离模式下列表页删除协同人
     *
     * @param isolationDelCoUserDTO
     * @return
     * @throws XbbException
     */
    @Override
    public TeamBatchVO delCoUserForIsolation(IsolationDelCoUserDTO isolationDelCoUserDTO) throws XbbException {

        TeamBatchVO teamBatchVO = new TeamBatchVO();

        int size = isolationDelCoUserDTO.getDataIdList().size();
        String corpid = isolationDelCoUserDTO.getCorpid();
        List<Long> dataIdList = isolationDelCoUserDTO.getDataIdList();
        Integer businessType = isolationDelCoUserDTO.getBusinessType();
        Long formId = isolationDelCoUserDTO.getFormId();
        UserVO loginUser = isolationDelCoUserDTO.getLoginUser();
        //校验数据权限
        List<TeamBatchPojo> teamBatchPojos = checkDataPermission4Isolation(dataIdList, businessType, formId, corpid, loginUser, UserTeamOperateTagEnum.DEL_COUSER);


        String redisPrefix = teamDataHelp.getRedisPrefix(isolationDelCoUserDTO.getSaasMark(), isolationDelCoUserDTO.getBusinessType());
        List<Long> lackIdList = dataLocking(isolationDelCoUserDTO.getDataIdList(), isolationDelCoUserDTO.getCorpid(), redisPrefix);

        List<TeamBatchPojo> batchPojo4Approval = teamHelp.checkDataIsApproval(isolationDelCoUserDTO.getDataIdList(), isolationDelCoUserDTO.getCorpid(), isolationDelCoUserDTO.getFormId(), isolationDelCoUserDTO.getSaasMark(), isolationDelCoUserDTO.getBusinessType(), UserTeamOperateTagEnum.DEL_COUSER);
        if(CollectionsUtil.isNotEmpty(batchPojo4Approval)){
            teamBatchPojos.addAll(batchPojo4Approval);
        }
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(isolationDelCoUserDTO, teamVerifyDTO);
        teamVerifyDTO.setTeamUserId(isolationDelCoUserDTO.getMainUserId());
        teamVerifyDTO.setDataId(isolationDelCoUserDTO.getDataIdList());
        teamVerifyDTO.setNewDelCoUserList(new HashSet<>(isolationDelCoUserDTO.getUserIdList()));
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setBatchTag(Constant.ONE);
        teamVerifyDTO.setLoginUser(isolationDelCoUserDTO.getLoginUser());

        teamBatchPojos.addAll(teamDataHelp.save(teamVerifyDTO));

        if (CollectionsUtil.isNotEmpty(lackIdList)){
            Map<Long, String> nameOrSeriNoMap = new HashMap<>();
            userTeamHelp.getEntityMap(teamVerifyDTO.getBusinessType(), lackIdList, teamVerifyDTO.getCorpid(), nameOrSeriNoMap, teamVerifyDTO.getSaasMark());
            List<String> lackName = new ArrayList<>(lackIdList.size());
            for (Long id : lackIdList) {
                lackName.add(nameOrSeriNoMap.getOrDefault(id, ""));
            }
            commonHelp.batchSameErrorPackage(lackName, UserTeamOperateTagEnum.DEL_COUSER.getName(),
                    UserTeamErrorCodeEnum.API_ERROR_271020.getCode(), UserTeamErrorCodeEnum.API_ERROR_271020.getMsg(), teamBatchPojos);
        }

        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
            commonHelp.batchFailMsg(teamBatchPojos, size, teamBatchVO);
        }
        return teamBatchVO;
    }

    /**
     * 列表页批量创建团队
     *
     * @param isolationCreateTeamDTO
     * @return
     */
    @Override
    public TeamBatchVO createTeam(IsolationCreateTeamDTO isolationCreateTeamDTO) throws XbbException {
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        if(isolationCreateTeamDTO.getName().length() > TeamMembersConstant.TEAM_NAME_MAX){
            TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsg(I18nMessageUtil.getMessage(TeamMembersConstant.CREATE_TEAM_FAIL_MESSAGE));
            teamBatchPojo.setFailMsgReason(UserTeamErrorCodeEnum.API_ERROR_271019.getMsg());
            teamBatchVO.setTeamBatchPojos(Arrays.asList(teamBatchPojo));
            teamBatchVO.setResultType(ListBatchResultEnum.OPERATE_FAIL.getAlias());
            teamBatchVO.setResultMsg(ListBatchResultEnum.OPERATE_FAIL.getMsg());
            return teamBatchVO;
        }
        int size = isolationCreateTeamDTO.getDataIdList().size();
        String corpid = isolationCreateTeamDTO.getCorpid();
        List<Long> dataIdList = isolationCreateTeamDTO.getDataIdList();
        Integer businessType = isolationCreateTeamDTO.getBusinessType();
        Long formId = isolationCreateTeamDTO.getFormId();
        UserVO loginUser = isolationCreateTeamDTO.getLoginUser();
        //校验数据权限
        List<TeamBatchPojo> teamBatchPojos = checkDataPermission4Isolation(dataIdList, businessType, formId, corpid, loginUser, UserTeamOperateTagEnum.ADD_TEAM_TAG);

        String redisPrefix = teamDataHelp.getRedisPrefix(isolationCreateTeamDTO.getSaasMark(), isolationCreateTeamDTO.getBusinessType());
        List<Long> lackIdList = dataLocking(isolationCreateTeamDTO.getDataIdList(), isolationCreateTeamDTO.getCorpid(), redisPrefix);

        List<TeamBatchPojo> batchPojo4Approval = teamHelp.checkDataIsApproval(isolationCreateTeamDTO.getDataIdList(), isolationCreateTeamDTO.getCorpid(), isolationCreateTeamDTO.getFormId(), isolationCreateTeamDTO.getSaasMark(), isolationCreateTeamDTO.getBusinessType(), UserTeamOperateTagEnum.ADD_TEAM_TAG);
        if(CollectionsUtil.isNotEmpty(batchPojo4Approval)){
            teamBatchPojos.addAll(batchPojo4Approval);
        }
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(isolationCreateTeamDTO, teamVerifyDTO);
        teamVerifyDTO.setDataId(isolationCreateTeamDTO.getDataIdList());
        Set<String> addMainUserList = new HashSet<>();
        addMainUserList.add(isolationCreateTeamDTO.getMainUserId());
        teamVerifyDTO.setNewAddMainUserList(addMainUserList);
        teamVerifyDTO.setTeamName(isolationCreateTeamDTO.getName());
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setOperateTag(UserTeamOperateTagEnum.ADD_TEAM_TAG.getOperateTag());
        teamVerifyDTO.setBatchTag(Constant.ONE);
        teamVerifyDTO.setLoginUser(isolationCreateTeamDTO.getLoginUser());

        teamBatchPojos.addAll(teamDataHelp.save(teamVerifyDTO));

        if (CollectionsUtil.isNotEmpty(lackIdList)){
            Map<Long, String> nameOrSeriNoMap = new HashMap<>();
            userTeamHelp.getEntityMap(teamVerifyDTO.getBusinessType(), lackIdList, teamVerifyDTO.getCorpid(), nameOrSeriNoMap, teamVerifyDTO.getSaasMark());
            List<String> lackName = new ArrayList<>(lackIdList.size());
            for (Long id : lackIdList) {
                lackName.add(nameOrSeriNoMap.getOrDefault(id, ""));
            }
            commonHelp.batchSameErrorPackage(lackName, UserTeamOperateTagEnum.ADD_TEAM_TAG.getName(),
                    UserTeamErrorCodeEnum.API_ERROR_271020.getCode(), UserTeamErrorCodeEnum.API_ERROR_271020.getMsg(), teamBatchPojos);
            /*TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
            teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.USED_BY_OTHER));
            commonHelp.mergeFailMsg(lackName, size, teamBatchPojo, I18nMessageUtil.getMessage(ListBatchConstant.DEL_CO_USER), teamBatchVO);
            teamBatchPojos.add(teamBatchPojo);*/
        }

        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
            commonHelp.batchFailMsg(teamBatchPojos, size, teamBatchVO);
        }

        return teamBatchVO;
    }

    /**
     * 列表页解散团队
     *
     * @param isolationDisbandTeamDTO
     * @return
     */
    @Override
    public TeamBatchVO disbandTeam(IsolationDisbandTeamDTO isolationDisbandTeamDTO) throws XbbException{
        TeamBatchVO teamBatchVO = new TeamBatchVO();

        int size = isolationDisbandTeamDTO.getDataIdList().size();
        String corpid = isolationDisbandTeamDTO.getCorpid();
        List<Long> dataIdList = isolationDisbandTeamDTO.getDataIdList();
        Integer businessType = isolationDisbandTeamDTO.getBusinessType();
        Long formId = isolationDisbandTeamDTO.getFormId();
        UserVO loginUser = isolationDisbandTeamDTO.getLoginUser();
        //校验数据权限
        List<TeamBatchPojo> teamBatchPojos = checkDataPermission4Isolation(dataIdList, businessType, formId, corpid, loginUser, UserTeamOperateTagEnum.DEL_TEAM_TAG);



        String redisPrefix = teamDataHelp.getRedisPrefix(isolationDisbandTeamDTO.getSaasMark(), isolationDisbandTeamDTO.getBusinessType());
        List<Long> lackIdList = dataLocking(isolationDisbandTeamDTO.getDataIdList(), isolationDisbandTeamDTO.getCorpid(), redisPrefix);

        List<TeamBatchPojo> batchPojo4Approval = teamHelp.checkDataIsApproval(isolationDisbandTeamDTO.getDataIdList(), isolationDisbandTeamDTO.getCorpid(), isolationDisbandTeamDTO.getFormId(), isolationDisbandTeamDTO.getSaasMark(), isolationDisbandTeamDTO.getBusinessType(), UserTeamOperateTagEnum.DEL_TEAM_TAG);
        if(CollectionsUtil.isNotEmpty(batchPojo4Approval)){
            teamBatchPojos.addAll(batchPojo4Approval);
        }
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        BeanUtil.copyProperties(isolationDisbandTeamDTO, teamVerifyDTO);
        teamVerifyDTO.setTeamUserId(isolationDisbandTeamDTO.getMainUserId());
        Set<String> newDelMainUserList = new HashSet<>();
        newDelMainUserList.add(isolationDisbandTeamDTO.getMainUserId());
        teamVerifyDTO.setNewDelMainUserList(newDelMainUserList);
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setDataId(isolationDisbandTeamDTO.getDataIdList());
        teamVerifyDTO.setOperateTag(UserTeamOperateTagEnum.DEL_TEAM_TAG.getOperateTag());
        teamVerifyDTO.setBatchTag(Constant.ONE);
        teamVerifyDTO.setLoginUser(isolationDisbandTeamDTO.getLoginUser());

        teamBatchPojos.addAll(teamDataHelp.save(teamVerifyDTO));

        if (CollectionsUtil.isNotEmpty(lackIdList)){
            Map<Long, String> nameOrSeriNoMap = new HashMap<>();
            userTeamHelp.getEntityMap(teamVerifyDTO.getBusinessType(), lackIdList, teamVerifyDTO.getCorpid(), nameOrSeriNoMap, teamVerifyDTO.getSaasMark());
            List<String> lackName = new ArrayList<>(lackIdList.size());
            for (Long id : lackIdList) {
                lackName.add(nameOrSeriNoMap.getOrDefault(id, ""));
            }
            commonHelp.batchSameErrorPackage(lackName, UserTeamOperateTagEnum.DEL_TEAM_TAG.getName(),
                    UserTeamErrorCodeEnum.API_ERROR_271020.getCode(), UserTeamErrorCodeEnum.API_ERROR_271020.getMsg(), teamBatchPojos);
        }

        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            teamBatchVO.setTeamBatchPojos(teamBatchPojos);
            commonHelp.batchFailMsg(teamBatchPojos, size, teamBatchVO);
        }

        return teamBatchVO;
    }

    @Override
    public TeamBatchVO changeMain(ChangeMainDTO changeMainDTO) throws XbbException {
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        Integer businessType = changeMainDTO.getBusinessType();
        Integer saasMark = changeMainDTO.getSaasMark();
        String corpid = changeMainDTO.getCorpid();
        int size = changeMainDTO.getDataIdList().size();
        if (size > StringConstant.MAX_SIZE) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200029);
        }

        TransmittableThreadLocalUtil.setValue(changeMainDTO.getSaasMark(), changeMainDTO.getBusinessType(), null, DistributorMarkEnum.OTHER.getCode());
        if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
            // 共享/隔离处理
            // 获取共享/隔离配置
            FormTeamSetEntity formTeamSetEntity = formTeamSetHelp.getFormTeamSet(corpid, changeMainDTO.getFormId(), saasMark, businessType, changeMainDTO.getDistributorMark());

            // 有共享/隔离的业务
            Integer model = formTeamSetEntity.getModel();
            //非旗舰版套餐默认走通用规则，旗舰版套餐就需要各种判断了。以及未设置过共享或隔离的走默认规则
            Integer feeType = commonHelp.getCurrentCompanyPackage(corpid);
            if (Objects.isNull(model) || !Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType())) {
                model = FormDefaultPatternEnum.getModelValueByBusinessType(businessType);
                formTeamSetEntity.setModel(model);
            }

            if (Objects.equals(model, FormPatternEnum.FORM_ISOLATION.getModel())) {
                // 隔离模式下移交一定要有被移交人 ,这边是个很特殊场景下的业务处理，用于支持API
                if (Objects.isNull(changeMainDTO.getOriginUserId())) {
                    throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_271033);
                }
            }
        }


        if (Objects.equals(SaasMarkEnum.PAAS.getCode(), saasMark)) {
            teamBatchVO = teamChangeMain(changeMainDTO);
            return teamBatchVO;
        }
        XbbRefTypeEnum business = XbbRefTypeEnum.getByCode(businessType);
        switch (business) {
            case CUSTOMER_MANAGEMENT:
            case CLUE:
            case CONTACT:
            case CONTRACT:
            case SALES_OPPORTUNITY:
            case REFUND:
            case QUOTATION:
            case SUPPLIER:
            case PURCHASE:
            case BOM_BILL:
            case PRODUCTION_ORDER:
            case ORDER:
            case RETURN:
            case MARKET_ACTIVITY:
            case WAREHOUSE:
            case PAYMENT:
            case PAYMENT_SHEET:
            case PAY_PLAN:
            case PAY_SHEET:
            case SUPPLIER_CONTACT:
                teamBatchVO = teamChangeMain(changeMainDTO);
                break;
            case RETURNED_PURCHASE:
            case ASSEMBLE:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case OTHER_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
            case CONTRACT_OUTSTOCK:
            case ORDER_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
            case TRANSFER:
            case INVENTORY:
            case COST_ADJUST:
                teamBatchVO = noTeamHandleOver(changeMainDTO);
                break;
            case DISTRIBUTOR_MANAGEMENT:
                teamBatchVO = distributorHandover(changeMainDTO);
                break;
            default:
                throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        return teamBatchVO;
    }

    /**
     * 有团队的移交功能
     *
     * @param changeMainDTO
     * @throws XbbException
     */
    private TeamBatchVO teamChangeMain(ChangeMainDTO changeMainDTO) throws XbbException{
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        List<Long> dataIdList = changeMainDTO.getDataIdList();
        UserVO loginUser = changeMainDTO.getLoginUser();
        int size = dataIdList.size();
        String corpid = changeMainDTO.getCorpid();
        Integer saasMark = changeMainDTO.getSaasMark();
        Integer businessType = changeMainDTO.getBusinessType();
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        List<TeamBatchPojo> teamBatchPojos = new ArrayList<>();
        //先把没有权限的直接移除，生成报错信息
        //校验数据权限(团队权限&共享权限)
        if (Objects.equals(changeMainDTO.getIsBatch(), BasicConstant.ZERO)){
            PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormDataWithTeam(corpid, saasMark, businessType, dataIdList.get(0));
            if (Objects.isNull(paasFormDataEntityExt)){
                return new TeamBatchVO();
            }
            VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
            boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
            if (!hasDataPermission){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), OperateTypeEnum.HANDOVER.getName()));
            }
        }else{
            //只有客户和线索的移交有共享隔离模式区别
            if(Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType) || Objects.equals(XbbRefTypeEnum.CLUE.getCode(), businessType)){
                FormTeamSetEntity formTeamSet = formTeamSetHelp.getFormTeamSet(corpid, changeMainDTO.getFormId(), saasMark, businessType, DistributorMarkEnum.OTHER.getCode());
                if(Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_SHARE.getModel())){
                    teamBatchPojos = checkDataPermission4Share(dataIdList, businessType, changeMainDTO.getFormId(), saasMark, corpid, loginUser, UserTeamOperateTagEnum.HANDOVER);
                }else if(Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_ISOLATION.getModel())){
                    teamBatchPojos = checkDataPermission4Isolation(dataIdList, businessType, changeMainDTO.getFormId(), corpid, loginUser, UserTeamOperateTagEnum.HANDOVER);
                }
            }else{
                teamBatchPojos = checkDataPermission4Share(dataIdList, businessType, changeMainDTO.getFormId(), saasMark, corpid, loginUser, UserTeamOperateTagEnum.HANDOVER);
            }
        }

        // 批量的数据锁
        String redisPrefix = teamDataHelp.getRedisPrefix(saasMark, changeMainDTO.getBusinessType());
        List<Long> lackIdList = dataLocking(dataIdList, changeMainDTO.getCorpid(), redisPrefix);

        List<TeamBatchPojo> checkBatchPojos = teamHelp.checkDataIsApproval(dataIdList, changeMainDTO.getCorpid(), changeMainDTO.getFormId(), saasMark, changeMainDTO.getBusinessType(), UserTeamOperateTagEnum.HANDOVER);
        if(CollectionUtils.isNotEmpty(checkBatchPojos)){
            teamBatchPojos.addAll(checkBatchPojos);
        }
        BeanUtil.copyProperties(changeMainDTO, teamVerifyDTO);
        if (!Objects.equals(BasicConstant.ZERO, changeMainDTO.getBatchTag())) {
            teamVerifyDTO.setBatchTag(BasicConstant.ONE);
        }
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setDataId(dataIdList);
        teamVerifyDTO.setOperateTag(UserTeamOperateTagEnum.HANDOVER.getOperateTag());
        teamVerifyDTO.setLoginUser(changeMainDTO.getLoginUser());

        teamBatchPojos.addAll(teamDataHelp.save(teamVerifyDTO));
        //这边会有重复提示
        List<Long> errorIdList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            errorIdList = teamBatchPojos.stream().map(TeamBatchPojo::getDataId).collect(Collectors.toList());
            lackIdList.removeAll(errorIdList);
        }
        if (CollectionsUtil.isNotEmpty(lackIdList)){
            Map<Long, String> nameOrSeriNoMap = new HashMap<>();
            userTeamHelp.getEntityMap(teamVerifyDTO.getBusinessType(), lackIdList, teamVerifyDTO.getCorpid(), nameOrSeriNoMap, teamVerifyDTO.getSaasMark());
            List<String> lackName = new ArrayList<>(lackIdList.size());
            for (Long id : lackIdList) {
                lackName.add(nameOrSeriNoMap.getOrDefault(id, ""));
            }
            commonHelp.batchSameErrorPackage(lackName, UserTeamOperateTagEnum.HANDOVER.getName(),
                    UserTeamErrorCodeEnum.API_ERROR_271020.getCode(), UserTeamErrorCodeEnum.API_ERROR_271020.getMsg(), teamBatchPojos);
        }

        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            if (!Objects.equals(BasicConstant.ZERO, changeMainDTO.getBatchTag())) {
                teamBatchVO.setTeamBatchPojos(teamBatchPojos);
                commonHelp.batchFailMsg(teamBatchPojos, size, teamBatchVO);
            }else {
                throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_271004.getCode(), teamBatchPojos.get(BasicConstant.ZERO).getFailMsgReason());
            }

        }
        return teamBatchVO;
    }

    /**
     * 没有团队的移交功能
     *
     * @param changeMainDTO
     * @return
     * @throws XbbException
     */
    private TeamBatchVO noTeamHandleOver(ChangeMainDTO changeMainDTO) throws XbbException{
        TeamBatchVO teamBatchVO = otherHandover(changeMainDTO);
        return teamBatchVO;
    }



    @Override
    public BaseVO addLabelBatch(AddLabelDTO addLabelDTO) throws XbbException {
        LabelBatchMessageVO labelBatchMessageVO = new LabelBatchMessageVO();
        // ErrorMessageVO errorMessageVO = new ErrorMessageVO();
        List<Long> dataIdList = addLabelDTO.getDataIdList();
        List<Long> addLabelIds = addLabelDTO.getLabelIds();
        String attr = addLabelDTO.getAttr();
        VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO();
        BeanUtil.copyProperties(addLabelDTO, verifyUpdatePermissionDTO);
        ProPermissionHelp.verifyEditPermission(verifyUpdatePermissionDTO);
        String corpid = addLabelDTO.getCorpid();
        Integer businessType = addLabelDTO.getBusinessType();
        Integer saasMark = addLabelDTO.getSaasMark();
        UserVO loginUser = addLabelDTO.getLoginUser();
        Map<Long, List<String>> ownerIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        businessUserTeamHelp.getUserIdMapSetShow(new HashSet<>(), dataIdList, corpid, businessType, false, ownerIdMap, coUserIdMap, DelEnum.NORMAL.getDel());
        if (Objects.equals(addLabelDTO.getIsBatch(), BasicConstant.ZERO)){
            PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormData(corpid, saasMark, businessType, dataIdList.get(0));
            if (Objects.isNull(paasFormDataEntityExt)){
                return new FormDataUpdateBatchVO();
            }
            paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
            paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
            verifyUpdatePermissionDTO.setPaasFormDataEntityExt(paasFormDataEntityExt);
            boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
            if (!hasDataPermission){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), OperateTypeEnum.ADD_LABEL.getName()));
            }
        }else{
            List<PaasFormDataEntityExt> paasFormDataEntityExtList = formDataHelp.getByDataIdList(dataIdList, businessType, saasMark, addLabelDTO.getFormId(), corpid);
            List<Long> errorDataIdList = new ArrayList<>();
            //数据库获取相关规则
            List<ShareRuleEntity> ruleEntities = sharePermissionHelp.getRuleEntities(corpid, addLabelDTO.getFormId(), loginUser.getUserId());
            for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
                paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
                paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
                verifyUpdatePermissionDTO.setPaasFormDataEntityExt(paasFormDataEntityExt);
                boolean hasDataPermission = commonPermissionHelp.checkPermission(verifyUpdatePermissionDTO);
                if(!hasDataPermission){
                    verifyUpdatePermissionDTO.setRuleEntities(ruleEntities);
                    hasDataPermission = sharePermissionHelp.verifySharePermission4EditWithRuleEngine(verifyUpdatePermissionDTO);
                }
                if (!hasDataPermission){
                    errorDataIdList.add(paasFormDataEntityExt.getId());
                }
            }
            if(CollectionUtils.isNotEmpty(errorDataIdList)){
                dataIdList.removeIf(errorDataIdList :: contains);
            }
        }
        Long formId = addLabelDTO.getFormId();
        PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
        PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();

        try {
            if (Objects.equals(addLabelDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                if (Objects.equals(formId, 0L)) {
                    //工单全部列表, 快速编辑处理

                    if (dataIdList != null && dataIdList.size() < 1) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
                    }
                    WorkOrderEntity workOrderEntity = workOrderModel.getByKey(dataIdList.get(0), corpid);
                    formId = workOrderEntity.getFormId();
                }
                WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(formId, corpid);
                BeanUtil.copyProperties(workOrderExplainEntity, paasFormExplainEntity);
            } else {
                paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
            }
            List<Long> labelIds = addLabelDTO.getLabelIds();
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMapByAttr(paasFormExplainEntity.getExplains(), addLabelDTO.getAttr());
            if (Objects.equals(addLabelDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                //工单
                WorkOrderFormEntity workOrderFormEntity = workOrderFormModel.getByKey(formId, corpid);
                BeanUtil.copyProperties(workOrderFormEntity, paasFormEntityExt);
            } else {
                paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
            }
            if(Objects.isNull(paasFormEntityExt)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            //产品列表打标签，添加子产品
            if (Objects.equals(addLabelDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())){
                ChildProductDTO childProductDTO = new ChildProductDTO();
                childProductDTO.setCorpid(corpid);
                childProductDTO.setParentProductId(dataIdList);
                PaasFormDataEsListVO esDataList = productService.getChildProductList(childProductDTO);
                List<PaasFormDataEntityExt> paasFormDataESList = esDataList.getPaasFormDataESList();
                paasFormDataESList.forEach(item->{
                    dataIdList.add(item.getDataId());
                });
            }
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            boolQueryBuilder.filter(termQuery("formId", addLabelDTO.getFormId()));
            boolQueryBuilder.filter(termsQuery(StringConstant.DATA_ID, dataIdList));
            boolQueryBuilder.filter(termQuery("del", 0));
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            // 排序
            sourceBuilder.sort(new FieldSortBuilder(FieldTypeEnum.UPDATETIME.getAlias()).order(SortOrder.DESC));
            sourceBuilder.query(boolQueryBuilder);
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, addLabelDTO.getBusinessType(), saasMark);
            XbbAggregatedPage byPage = esHelper.findByPage(indexTypeEnum, boolQueryBuilder, PaasFormDataEntityExt.class, null, 1, dataIdList.size(), null);
            List<PaasFormDataEntityExt> paasFormDataEntityExts =byPage.getContent();
            //进销存业务校验
            if (ProductConstant.EFFECT_PRODUCT_COST_AND_STOCK.contains(addLabelDTO.getBusinessType())) {
                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                    //结账校验
                    JSONObject data = paasFormDataEntityExt.getData();
                    Long date = data.getLong(AssembleEnum.ASSEMBLE_TIME.getAttr());
                    //结账中校验
                    String redisHelperValue = paasRedisHelper.getValue(RedisPrefixConstant.SETTLE_ACCOUNTS, corpid);
                    if (StringUtil.isNotEmpty(redisHelperValue)) {
                        if (date <= DateTimeUtil.getTodayEndInt(Long.valueOf(redisHelperValue))) {
                            throw new XbbException(SettleAccountErrorCodeEnum.API_ERROR_254007);
                        }
                    }
                    SettleAccountsEntity accountsEntity = settleAccountsModel.getLastSettleAccounts(corpid);
                    //校验日期是否受结账限制
                    if (Objects.nonNull(accountsEntity) && Objects.nonNull(accountsEntity.getCheckOutTime())) {
                        if (date <= DateTimeUtil.getTodayEndInt(accountsEntity.getCheckOutTime())) {
                            throw new XbbException(OutstockErrorCodeEnum.API_ERROR_212051);
                        }
                    }
                }
            }
            // 判断审批中的数据
            // 审批通过后是否允许编辑
            boolean editAfterFinished = paasProcessTemplateModel.getEditAfterFinished(addLabelDTO.getAppId(),addLabelDTO.getMenuId(),addLabelDTO.getFormId(),addLabelDTO.getLoginUser());
            List<PaasFormDataEntityExt> dataList = new ArrayList<>(paasFormDataEntityExts);
            // 审批后能否编辑
            paasProcessTemplateModel.checkEditAfterFinished(editAfterFinished, dataList);


            List<PaasFormDataEntityExt> addBatchList = new ArrayList<>();
            // 错误 -> 如果数据现有的标签都包含要打的标签,产品这样说
            List<PaasFormDataEntityExt> errorBatchList = new ArrayList<>();

            // 获取需要更新的与不更新的
            for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                JSONArray jsonArray = new JSONArray();
                jsonArray = paasFormDataEntityExt.getData().getJSONArray(attr);
                if (CollectionsUtil.isNotEmpty(jsonArray)){
                    List<Long> longs = JSON.parseArray(jsonArray.toJSONString(), Long.class);
                    // 现有的标签已经满足就不需要更新
                    if (longs.containsAll(addLabelIds)){
                        continue;
                    }
                    for (Long addLabelId : addLabelIds) {
                        if (!longs.contains(addLabelId)){
                            jsonArray.add(addLabelId);
                        }
                    }
                } else {
                    // 原先没有标签
                    jsonArray = new JSONArray();
                    jsonArray.addAll(addLabelIds);
                }
                // 正式用的
                if (jsonArray.size() > PaasConstant.LIMIT_MAX_NUM_DATA_LABEL){
                // 测试用的
                // if (jsonArray.size() > BasicConstant.TWO){
                    errorBatchList.add(paasFormDataEntityExt);
                    continue;
                }
                paasFormDataEntityExt.getData().put(attr, jsonArray);
                addBatchList.add(paasFormDataEntityExt);
            }
            // 修改字段

            FieldAttrEntity fieldAttrEntity = explainMap.get(addLabelDTO.getAttr());

            FormDataUpdateBatchDTO formDataUpdateBatchDTO = new FormDataUpdateBatchDTO();
            BeanUtil.copyProperties(addLabelDTO, formDataUpdateBatchDTO);
            checkEditPermission(fieldAttrEntity, formDataUpdateBatchDTO, paasFormDataEntityExts);

            if (CollectionsUtil.isNotEmpty(addBatchList)) {
                if (SaasMarkEnum.SAAS.getCode().equals(saasMark)) {
                    Integer fieldType = FieldTypeEnum.LABEL.getType();
                    XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
                    if (Objects.equals(0, fieldAttrEntity.getIsRedundant())) {
                        Set<String> saasEditAttrSet = ExplainUtil.getSaasEditAttr(xbbRefTypeEnum);
                        Set<Integer> editAttrFieldTypeSet = EditFieldTypeEnum.getEditFieldTypeSet();
                        // 可编辑字段列表不为空，并且包含该字段
                        boolean saasEditAttr = !saasEditAttrSet.isEmpty() && !saasEditAttrSet.contains(addLabelDTO.getAttr());
                        if (saasEditAttr
                                || !editAttrFieldTypeSet.contains(fieldType)) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EDIT);
                        }
                    }
                    batchLabelAttr(addLabelDTO, addBatchList, xbbRefTypeEnum, true);
                } else {
                    Map<String, FieldAttrEntity> paasexplainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
                    FieldAttrEntity paasFieldAttrEntity = paasexplainMap.get(attr);
                    List<UpdateDataEntity> jsonObjectList = new ArrayList<>();
                    for (PaasFormDataEntityExt formData: addBatchList) {
                        JSONObject data = new JSONObject();
                        data.put(addLabelDTO.getAttr(), formData.getData().get(attr));
                        UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(formData.getId(), data, corpid);
                        jsonObjectList.add(updateDataEntity);
                    }
                    paasFormDataModel.updateBatch(jsonObjectList, corpid);
                }
            }
            // 错误信息处理
            StringBuilder errorMsg = new StringBuilder();
            List<FieldAttrEntity> list = new ArrayList<>();
            String titleAttr = null;
            ErrorMessagePojo  errorMessagePojo = new ErrorMessagePojo();
            List<ErrorMessagePojo> errorMessagePojoList = new ArrayList<>();
            if (!CollectionsUtil.isEmpty(errorBatchList)){
                // 获取需要拼接的attr
                List<FormTitlePoJo> titleList = JSONArray.parseArray(paasFormEntityExt.getCustomTitle()).toJavaList(FormTitlePoJo.class);
                if (CollectionsUtil.isNotEmpty(titleList)){
                    titleAttr = titleList.get(0).getAttr();
                } else {
                    LinkKeyExplainListDTO linkKeyExplainListDTO = new LinkKeyExplainListDTO();
                    BeanUtil.copyProperties(addLabelDTO, linkKeyExplainListDTO);
                    LinkKeyExplainListVO linkKeyExplainListVO = paasFormExplainService.linkKeyList(linkKeyExplainListDTO);
                    FieldAttrEntity attrEntity = null;
                    if (Objects.nonNull(linkKeyExplainListVO)) {
                        attrEntity = linkKeyExplainListVO.getFormExplainList().get(0);
                    }
                }
                for(PaasFormDataEntityExt paasFormDataEntityExt : errorBatchList){
                    JSONObject data = paasFormDataEntityExt.getData();
                    if (StringUtil.isEmpty(titleAttr)){
                        errorMsg.append(errorBatchList.size()).append(I18nMessageUtil.getMessage(MessageConstant.NUM_DATA));
                        break;
                    }
                    if (Objects.nonNull(data.get(titleAttr))){
                        errorMsg.append(data.get(titleAttr).toString()).append(",");
                    }
                }
                labelBatchMessageVO.setResultMsg(errorMsg.toString() + I18nMessageUtil.getMessage(MessageConstant.TAG_FAILED));
                labelBatchMessageVO.setResultType("error");
                labelBatchMessageVO.setFailResource(I18nMessageUtil.getMessage(MessageConstant.FAILED_RESOURCE_ADD));
                // errorMessagePojo.setMessage(errorMsg.toString() + I18nMessageUtil.getMessage(MessageConstant.TAG_FAILED));
                // errorMessagePojoList.add(errorMessagePojo);
                // errorMessageVO.setMessageList(errorMessagePojoList);
            } else {
                labelBatchMessageVO.setResultMsg(I18nMessageUtil.getMessage(MessageConstant.SUCCESS_TO_SET_LABEL));
                labelBatchMessageVO.setResultType("success");
                //
                // errorMessagePojoList.add(errorMessagePojo);
                // errorMessageVO.setMessageList(errorMessagePojoList);
            }
        } catch (XbbException e) {
            LOG.error("批量打标签失败");
            throw e;
        } catch (Exception e){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return labelBatchMessageVO;
    }

    @Override
    public BaseVO removeLabelbatch(RemoveLableDTO removeLableDTO) throws XbbException {
        LabelBatchMessageVO labelBatchMessageVO = new LabelBatchMessageVO();
        List<Long> dataIdList = removeLableDTO.getDataIdList();
        List<Long> addLabelIds = removeLableDTO.getLabelIds();
        String attr = removeLableDTO.getAttr();
        VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO();
        BeanUtil.copyProperties(removeLableDTO, verifyUpdatePermissionDTO);
        ProPermissionHelp.verifyEditPermission(verifyUpdatePermissionDTO);
        String corpid = removeLableDTO.getCorpid();
        Integer businessType = removeLableDTO.getBusinessType();
        Integer saasMark = removeLableDTO.getSaasMark();
        UserVO loginUser = removeLableDTO.getLoginUser();
        Map<Long, List<String>> ownerIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        businessUserTeamHelp.getUserIdMapSetShow(new HashSet<>(), dataIdList, corpid, businessType, false, ownerIdMap, coUserIdMap, DelEnum.NORMAL.getDel());
        if (Objects.equals(removeLableDTO.getIsBatch(), BasicConstant.ZERO)){
            PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormData(corpid, saasMark, businessType, dataIdList.get(0));
            if (Objects.isNull(paasFormDataEntityExt)){
                return new FormDataUpdateBatchVO();
            }
            paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
            paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
            verifyUpdatePermissionDTO.setPaasFormDataEntityExt(paasFormDataEntityExt);
            boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
            if (!hasDataPermission){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050.getCode(), String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), OperateTypeEnum.REMOVE_LABEL.getName()));
            }
        }else{
            List<PaasFormDataEntityExt> paasFormDataEntityExtList = formDataHelp.getByDataIdList(dataIdList, businessType, saasMark, removeLableDTO.getFormId(), corpid);
            List<Long> errorDataIdList = new ArrayList<>();
            //数据库获取相关规则
            List<ShareRuleEntity> ruleEntities = sharePermissionHelp.getRuleEntities(corpid, removeLableDTO.getFormId(), loginUser.getUserId());
            for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExtList) {
                paasFormDataEntityExt.getData().put(FieldTypeEnum.OWNERID.getAlias(), ownerIdMap.get(paasFormDataEntityExt.getId()));
                paasFormDataEntityExt.getData().put(FieldTypeEnum.COUSERID.getAlias(), coUserIdMap.get(paasFormDataEntityExt.getId()));
                verifyUpdatePermissionDTO.setPaasFormDataEntityExt(paasFormDataEntityExt);
                boolean hasDataPermission = commonPermissionHelp.checkPermission(verifyUpdatePermissionDTO);
                if(!hasDataPermission){
                    verifyUpdatePermissionDTO.setRuleEntities(ruleEntities);
                    hasDataPermission = sharePermissionHelp.verifySharePermission4EditWithRuleEngine(verifyUpdatePermissionDTO);
                }
                if (!hasDataPermission){
                    errorDataIdList.add(paasFormDataEntityExt.getId());
                }
            }
            if(CollectionUtils.isNotEmpty(errorDataIdList)){
                dataIdList.removeIf(errorDataIdList :: contains);
            }
        }
        Long formId = removeLableDTO.getFormId();
        PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
        PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
        try {
            if (Objects.equals(removeLableDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                if (Objects.equals(formId, 0L)) {
                    //工单全部列表, 快速编辑处理

                    if (dataIdList != null && dataIdList.size() < 1) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
                    }
                    WorkOrderEntity workOrderEntity = workOrderModel.getByKey(dataIdList.get(0), corpid);
                    formId = workOrderEntity.getFormId();
                }
                WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(formId, corpid);
                BeanUtil.copyProperties(workOrderExplainEntity, paasFormExplainEntity);
            } else {
                paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
            }
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMapByAttr(paasFormExplainEntity.getExplains(), removeLableDTO.getAttr());
            if (Objects.equals(removeLableDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                //工单
                WorkOrderFormEntity workOrderFormEntity = workOrderFormModel.getByKey(formId, corpid);
                BeanUtil.copyProperties(workOrderFormEntity, paasFormEntityExt);
            } else {
                paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
            }
            if(Objects.isNull(paasFormEntityExt)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            //产品列表批量删除标签，添加子产品
            if (Objects.equals(removeLableDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())){
                ChildProductDTO childProductDTO = new ChildProductDTO();
                childProductDTO.setCorpid(corpid);
                childProductDTO.setParentProductId(dataIdList);
                PaasFormDataEsListVO esDataList = productService.getChildProductList(childProductDTO);
                List<PaasFormDataEntityExt> paasFormDataESList = esDataList.getPaasFormDataESList();
                paasFormDataESList.forEach(item->{
                    dataIdList.add(item.getDataId());
                });
            }
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            boolQueryBuilder.filter(termQuery("formId", removeLableDTO.getFormId()));
            boolQueryBuilder.filter(termsQuery(StringConstant.DATA_ID, dataIdList));
            boolQueryBuilder.filter(termQuery("del", 0));
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            // 排序
            sourceBuilder.sort(new FieldSortBuilder(FieldTypeEnum.UPDATETIME.getAlias()).order(SortOrder.DESC));
            sourceBuilder.query(boolQueryBuilder);
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, removeLableDTO.getBusinessType(), saasMark);
            // 设置join_field(fix bug 34994 : 不添加这个限制的话，term：dataId 会把 sub_form_data也查出来,导致 size会不匹配主数据的值)
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
            List<Long> errorList = new ArrayList<>();
            List<PaasFormDataEntityExt> paasFormDataEntityExts = paasEsModel.list(sourceBuilder, indexTypeEnum, new ArrayList<>(), 1, dataIdList.size());
//进销存业务校验
            if (ProductConstant.EFFECT_PRODUCT_COST_AND_STOCK.contains(removeLableDTO.getBusinessType())) {
                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                    //结账校验
                    JSONObject data = paasFormDataEntityExt.getData();
                    Long date = data.getLong(AssembleEnum.ASSEMBLE_TIME.getAttr());
                    //结账中校验
                    String redisHelperValue = paasRedisHelper.getValue(RedisPrefixConstant.SETTLE_ACCOUNTS, corpid);
                    if (StringUtil.isNotEmpty(redisHelperValue)) {
                        if (date <= DateTimeUtil.getTodayEndInt(Long.valueOf(redisHelperValue))) {
                            throw new XbbException(SettleAccountErrorCodeEnum.API_ERROR_254007);
                        }
                    }
                    SettleAccountsEntity accountsEntity = settleAccountsModel.getLastSettleAccounts(corpid);
                    //校验日期是否受结账限制
                    if (Objects.nonNull(accountsEntity) && Objects.nonNull(accountsEntity.getCheckOutTime())) {
                        if (date <= DateTimeUtil.getTodayEndInt(accountsEntity.getCheckOutTime())) {
                            throw new XbbException(OutstockErrorCodeEnum.API_ERROR_212051);
                        }
                    }
                }
            }
            // 判断审批中的数据
            // 审批通过后是否允许编辑
            boolean editAfterFinished = paasProcessTemplateModel.getEditAfterFinished(removeLableDTO.getAppId(),removeLableDTO.getMenuId(),removeLableDTO.getFormId(),removeLableDTO.getLoginUser());
            List<PaasFormDataEntityExt> dataList = new ArrayList<>(paasFormDataEntityExts);
            // 审批后能否编辑
            paasProcessTemplateModel.checkEditAfterFinished(editAfterFinished, dataList);


            List<PaasFormDataEntityExt> addBatchList = new ArrayList<>();
            // 错误 -> 如果数据现有的标签都包含要打的标签,产品这样说
            List<PaasFormDataEntityExt> errorBatchList = new ArrayList<>();

            // 获取需要更新的与不更新的
            FieldAttrEntity fieldAttrEntity = explainMap.get(removeLableDTO.getAttr());

            FormDataUpdateBatchDTO formDataUpdateBatchDTO = new FormDataUpdateBatchDTO();
            BeanUtil.copyProperties(removeLableDTO, formDataUpdateBatchDTO);
            checkEditPermission(fieldAttrEntity, formDataUpdateBatchDTO, paasFormDataEntityExts);


            Integer required = fieldAttrEntity.getRequired();
            List<Long> longs = new ArrayList<>();
            for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                JSONArray jsonArray = paasFormDataEntityExt.getData().getJSONArray(attr);
                if (CollectionsUtil.isNotEmpty(jsonArray)){
                    longs = jsonArray.toJavaList(Long.class);
                    for (Long item : addLabelIds) {
                        if (longs.contains(item)) {
                            longs.remove(item);
                        }
                    }
                    if (Objects.equals(required, BasicConstant.ONE) && CollectionsUtil.isEmpty(longs)){
                        errorBatchList.add(paasFormDataEntityExt);
                        continue;
                    }
                    paasFormDataEntityExt.getData().put(attr, longs);
                }
                addBatchList.add(paasFormDataEntityExt);
            }
            // 修改字段
            AddLabelDTO addLabelDTO = new AddLabelDTO();
            BeanUtil.copyProperties(removeLableDTO, addLabelDTO);
            if (CollectionsUtil.isNotEmpty(addBatchList)) {
                if (SaasMarkEnum.SAAS.getCode().equals(saasMark)) {
                    Integer fieldType = FieldTypeEnum.LABEL.getType();
                    XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
                    if (Objects.equals(0, fieldAttrEntity.getIsRedundant())) {
                        Set<String> saasEditAttrSet = ExplainUtil.getSaasEditAttr(xbbRefTypeEnum);
                        Set<Integer> editAttrFieldTypeSet = EditFieldTypeEnum.getEditFieldTypeSet();
                        // 可编辑字段列表不为空，并且包含该字段
                        boolean saasEditAttr = !saasEditAttrSet.isEmpty() && !saasEditAttrSet.contains(removeLableDTO.getAttr());
                        if (saasEditAttr
                                || !editAttrFieldTypeSet.contains(fieldType)) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EDIT);
                        }
                    }
                    batchLabelAttr(addLabelDTO, addBatchList, xbbRefTypeEnum, false);
                } else {
                    Map<String, FieldAttrEntity> paasexplainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
                    FieldAttrEntity paasFieldAttrEntity = paasexplainMap.get(attr);
                    List<UpdateDataEntity> jsonObjectList = new ArrayList<>();
                    for (PaasFormDataEntityExt formData: addBatchList) {
                        JSONObject data = new JSONObject();
                        data.put(removeLableDTO.getAttr(), formData.getData().get(attr));
                        UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(formData.getId(), data, corpid);
                        jsonObjectList.add(updateDataEntity);
                    }
                    paasFormDataModel.updateBatch(jsonObjectList, corpid);
                }
            }
            // 错误信息处理
            StringBuilder errorMsg = new StringBuilder();
            List<FieldAttrEntity> list = new ArrayList<>();
            String titleAttr =null ;
            ErrorMessagePojo  errorMessagePojo = new ErrorMessagePojo();
            List<ErrorMessagePojo> errorMessagePojoList = new ArrayList<>();
            if (!CollectionsUtil.isEmpty(errorBatchList)){
                // 获取需要拼接的attr
                List<FormTitlePoJo> titleList = JSONArray.parseArray(paasFormEntityExt.getCustomTitle()).toJavaList(FormTitlePoJo.class);
                if (CollectionsUtil.isNotEmpty(titleList)){
                    titleAttr = titleList.get(0).getAttr();
                } else {
                    LinkKeyExplainListDTO linkKeyExplainListDTO = new LinkKeyExplainListDTO();
                    BeanUtil.copyProperties(addLabelDTO, linkKeyExplainListDTO);
                    LinkKeyExplainListVO linkKeyExplainListVO = paasFormExplainService.linkKeyList(linkKeyExplainListDTO);
                    FieldAttrEntity attrEntity = null;
                    if (Objects.nonNull(linkKeyExplainListVO)) {
                        attrEntity = linkKeyExplainListVO.getFormExplainList().get(0);
                    }
                }
                for(PaasFormDataEntityExt paasFormDataEntityExt : errorBatchList){
                    JSONObject data = paasFormDataEntityExt.getData();
                    if (StringUtil.isEmpty(titleAttr)){
                        errorMsg.append(errorBatchList.size()).append(I18nMessageUtil.getMessage(MessageConstant.NUM_DATA));
                        break;
                    }
                    if (Objects.nonNull(data.get(titleAttr))){
                        errorMsg.append(data.get(titleAttr).toString()).append(",");
                    }
                }
                // errorMessagePojo.setMessage(errorMsg.toString() + I18nMessageUtil.getMessage(MessageConstant.FAILED_TO_REMOVE_LABEL));
                // errorMessagePojoList.add(errorMessagePojo);
                // errorMessageVO.setMessageList(errorMessagePojoList);
                labelBatchMessageVO.setResultMsg(errorMsg.toString() + I18nMessageUtil.getMessage(MessageConstant.FAILED_TO_REMOVE_LABEL));
                labelBatchMessageVO.setResultType("error");
                labelBatchMessageVO.setFailResource(I18nMessageUtil.getMessage(MessageConstant.FAILED_RESOURCE_REMOVE));
            } else {
                labelBatchMessageVO.setResultType("success");
                labelBatchMessageVO.setResultMsg(I18nMessageUtil.getMessage(MessageConstant.SUCCESS_TO_SET_LABEL));
            }
        } catch (XbbException e) {
            LOG.error("批量移除标签失败");
            throw e;
        } catch (Exception e){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return labelBatchMessageVO;
    }

    /**
     *
     * 更换公海分组
     * @author lijiangren
     * @date 2022-04-20 13 45
     */
    @Override
    public BaseVO changePublicGroupBatch(UpdatePublicGroupDTO updatePublicGroupDTO) throws XbbException {
        TeamBatchVO teamBatchVO = new TeamBatchVO();
        List<Long> dataIdList = updatePublicGroupDTO.getDataIdList();
        Long groupId = updatePublicGroupDTO.getGroupId();
        Integer businessType = updatePublicGroupDTO.getBusinessType();
        String attr = updatePublicGroupDTO.getAttr();
        String corpid = updatePublicGroupDTO.getCorpid();
        Long formId = updatePublicGroupDTO.getFormId();

        //高级模式、编辑权限、公海池变更权限校验
        if (!commonHelp.isPublicPoolSeniorModel(corpid,businessType)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.NO_CHANGE_PUBLIC_POOL_GROUP);
        }

        VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO();
        BeanUtil.copyProperties(updatePublicGroupDTO, verifyUpdatePermissionDTO);
        ProPermissionHelp.verifyEditPermission(verifyUpdatePermissionDTO);

        TagTypeEnum tagTypeEnum = TagTypeEnum.TRANSFER_CUSTOMER_RULE;
        if (Objects.equals(businessType,XbbRefTypeEnum.CLUE.getCode())){
            tagTypeEnum = TagTypeEnum.TRANSFER_CLUE_RULE;
        }
        try {

            PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
            if(Objects.isNull(paasFormEntityExt)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            //判断公海分组存不存在
            PublicGroupSeniorEntity publicGroupSeniorEntity = publicGroupSeniorModel.getByKey(groupId, corpid);
            if(Objects.isNull(publicGroupSeniorEntity)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PUBLIC_POOL_GROUP_NOT_EXIST);
            }

            String groupIdStr = groupId.toString();
            if (Objects.equals(publicGroupSeniorEntity.getGroupType(), BasicConstant.TWO)) {
                groupIdStr = "";
            }

            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            boolQueryBuilder.filter(termQuery("formId", updatePublicGroupDTO.getFormId()));
            boolQueryBuilder.filter(termsQuery(StringConstant.DATA_ID, dataIdList));
            boolQueryBuilder.filter(termQuery("del", 0));
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            // 排序
            sourceBuilder.sort(new FieldSortBuilder(FieldTypeEnum.UPDATETIME.getAlias()).order(SortOrder.DESC));
            sourceBuilder.query(boolQueryBuilder);
            IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_FORM_DATA;
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), updatePublicGroupDTO.getSaasMark())) {
                indexTypeEnum = IndexTypeEnum.getByCode(businessType);
            }
            XbbAggregatedPage byPage = esHelper.findByPage(indexTypeEnum, boolQueryBuilder, PaasFormDataEntityExt.class, null, 1, dataIdList.size(), null);
            List<PaasFormDataEntityExt> paasFormDataEntityExts = byPage.getContent();
            List<TeamBatchPojo> groupTeamBatchPojos = null;
            if (CollectionsUtil.isNotEmpty(paasFormDataEntityExts)) {
                //分组管理员权限校验
                List<Long> newDataIdList = paasFormDataEntityExts.stream().map(PaasFormDataEntityExt::getDataId).collect(Collectors.toList());
                String oprateTagName = OperateTypeEnum.BATCH_CHANGE_PUBLIC_GROUP.getName();
                groupTeamBatchPojos = publicGroupSeniorService.publicGroupVerify(corpid,businessType,formId,oprateTagName,updatePublicGroupDTO.getLoginUser(),paasFormDataEntityExts,newDataIdList);

                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                    if (newDataIdList.contains(paasFormDataEntityExt.getDataId())) {
                        //变更公海分组集合
                        JSONObject temp = new JSONObject();
                        temp.put(attr, groupIdStr);
                        UpdateDataEntity updateData = ExplainUtil.getUpdateData(paasFormDataEntityExt.getDataId(), temp, corpid);
                        updateDataEntityList.add(updateData);
                    }
                }
                //批量更新公海池分组
                if (CollectionsUtil.isNotEmpty(updateDataEntityList)) {
                    proUpdateHelp.updateBatch(1, businessType, corpid, updateDataEntityList);
                    publicSeniorLogHelp.saveBatchChangePublicGroup(paasFormDataEntityExts,corpid,businessType,paasFormEntityExt.getName(),publicGroupSeniorEntity.getName(),updatePublicGroupDTO.getUserId(),updatePublicGroupDTO.getLoginUserName(),updatePublicGroupDTO.getHttpHeader());
                }
                if (CollectionsUtil.isNotEmpty(newDataIdList)) {
                    //变更公海分组，移除转移公海池的标签
                    tagLinkModel.deleteTagByTagTypeAndRefIdIn(corpid, tagTypeEnum.getCode(), newDataIdList);
                }
            }

            packageDistributionError(updatePublicGroupDTO.getBusinessType(), updatePublicGroupDTO.getSaasMark(), groupTeamBatchPojos, null, null,
                    corpid, teamBatchVO, dataIdList.size(), UserTeamOperateTagEnum.GET_CUSTOMER.getName());

        } catch (XbbException e) {
            LOG.error("批量变更公海分组失败");
            throw e;
        } catch (Exception e){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return teamBatchVO;
    }


    @Override
    public BaseVO joinCommunicatePlan(FormDataAddDTO formDataAddDTO) throws XbbException {
        formDataAddDTO.setSerialNo("");
        JSONObject dataList = formDataAddDTO.getDataList();
        JSONArray customerArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataList, CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), new JSONArray());
        for (Object obj : customerArr) {
            JSONObject data = new JSONObject();
            data.putAll(dataList);
            JSONArray singCustomerArr = new JSONArray();
            JSONObject customerObj = (JSONObject) obj;
            String name = customerObj.getString(StringConstant.SAAS_LINK_BUSINESS_NAME);
            if (Objects.isNull(name)) {
                name = "";
            }
            singCustomerArr.add(customerObj);
            data.put(CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), singCustomerArr);
            data.put(CommunicatePlanEnum.NAME.getAttr(), name + I18nMessageUtil.getMessage(I18nStringConstant.COMMUNICATE_PLAN));
            formDataAddDTO.setDataList(data);
            paasFormDataService.add(formDataAddDTO);
        }
        return new BaseVO();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseVO pushNotify(FormDataAddDTO formDataAddDTO) throws XbbException {
        Integer isBatch = formDataAddDTO.getIsBatch();
        // 先copy一份，防止dataList里有些数据保存后置为null
        Object dataListObj = CloneUtil.deepClone(formDataAddDTO.getDataList());
        JSONObject oldDataList = JsonHelperUtil.parseObject(dataListObj.toString());
        // 跟进提醒保存
        Integer linkBusinessType = notifyBeforeSave(formDataAddDTO);
        JSONObject dataList = formDataAddDTO.getDataList();
        // 访客计划保存
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(linkBusinessType);;
        if (Objects.nonNull(dataList.get(PushNotifyEnum.ENTER_COMMUNICATE_PLAN.getAttr())) && dataList.getBooleanValue(PushNotifyEnum.ENTER_COMMUNICATE_PLAN.getAttr())) {
            JSONArray jsonArray = new JSONArray();
            JSONArray refIdArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataList, PushNotifyEnum.NOTIFY_NAME.getAttr(), jsonArray);
            List<Long> refIds = refIdArr.toJavaList(Long.class);
            showFormatHelp.formatLinkBusiness4Show(dataList, PushNotifyEnum.NOTIFY_NAME.getAttr(), PushNotifyEnum.NOTIFY_NAME_LINKED_TEXT.getAttr(), PushNotifyEnum.NOTIFY_NAME.getFieldType());
            JSONArray notifyNameArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataList, PushNotifyEnum.NOTIFY_NAME.getAttr(), new JSONArray());
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, formDataAddDTO.getCorpid());
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            param.put(ParameterConstant.ID_IN, refIds);
            JSONArray customerArr = new JSONArray();
            switch (redundantTemplateTypeEnum) {
                case CUSTOMER:
                    customerArr = notifyNameArr;
                    break;
                case CONTRACT:
                    List<ContractEntityExt> contractEntityExts = contractModel.findEntitys(param);
                    for (ContractEntityExt contractEntityExt : contractEntityExts) {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, FastJsonHelper.getLongOrDefaultFromFormData(contractEntityExt.getData(), ContractEnum.LINK_CUSTOMER.getAttr(), 0L));
                        jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_NAME, FastJsonHelper.getStringOrDefaultFromFormData(contractEntityExt.getData(), ContractEnum.LINK_CUSTOMER_HIDE.getAttr(), ""));
                        customerArr.add(jsonObject);
                    }
                    break;
                case SALES_OPPORTUNITY:
                    List<OpportunityEntityExt> opportunityEntityExts = opportunityModel.findEntitys(param);
                    for (OpportunityEntityExt opportunityEntityExt : opportunityEntityExts) {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, FastJsonHelper.getLongOrDefaultFromFormData(opportunityEntityExt.getData(), SalesOpportunityEnum.CUSTOMER_NAME.getAttr(), 0L));
                        jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_NAME, FastJsonHelper.getStringOrDefaultFromFormData(opportunityEntityExt.getData(), SalesOpportunityEnum.CUSTOMER_NAME_LINK_TEXT.getAttr(), ""));
                        customerArr.add(jsonObject);
                    }
                    break;
                case QUOTATION:
                    List<QuotationEntityExt> quotationEntityExts = quotationModel.findEntitys(param);
                    for (QuotationEntityExt quotationEntityExt : quotationEntityExts) {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, FastJsonHelper.getLongOrDefaultFromFormData(quotationEntityExt.getData(), QuotationEnum.CUSTOMER_ID.getAttr(), 0L));
                        jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_NAME, FastJsonHelper.getStringOrDefaultFromFormData(quotationEntityExt.getData(), QuotationEnum.CUSTOMER_NAME.getAttr(), ""));
                        customerArr.add(jsonObject);
                    }
                    break;
                case CLUE:
                    break;
                default:
                    throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
            }
            JSONObject planDataList = new JSONObject();
            FormDataAddDTO planAddDTO = new FormDataAddDTO();
            BeanUtil.copyProperties(formDataAddDTO, planAddDTO);
            PaasFormExplainEntity planExplain = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), formDataAddDTO.getCorpid());
            BeanUtil.copyProperties(planExplain, planAddDTO);
            planDataList.put(CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), customerArr);
            planDataList.put(CommunicatePlanEnum.EXECUTOR.getAttr(), FastJsonHelper.getJsonArrOrDefaultFromFormData(dataList, PushNotifyEnum.EXECUTOR.getAttr(), jsonArray));
            planDataList.put(CommunicatePlanEnum.EXECUTOR_LINKED_TEXT.getAttr(), FastJsonHelper.getJsonArrOrDefaultFromFormData(dataList, PushNotifyEnum.EXECUTOR_LINKED_TEXT.getAttr(), jsonArray));
            planDataList.put(CommunicatePlanEnum.TARGET.getAttr(), "");
            planDataList.put(CommunicatePlanEnum.COMMUNICATE_TIME.getAttr(), getIntegerOrDefaultFromFormData(dataList, PushNotifyEnum.COMMUNICATE_TIME.getAttr(), BasicConstant.ZERO));
            planDataList.put(CommunicatePlanEnum.NOTIFY_TYPE.getAttr(), FastJsonHelper.getStringOrDefaultFromFormData(dataList, PushNotifyEnum.NOTIFY_TYPE.getAttr(), ""));
            planDataList.put(CommunicatePlanEnum.NOTIFY_TIME.getAttr(), getIntegerOrDefaultFromFormData(dataList, PushNotifyEnum.NOTIFY_TIME.getAttr(), BasicConstant.ZERO));
            planDataList.put(CommunicatePlanEnum.MEMO.getAttr(), FastJsonHelper.getStringOrDefaultFromFormData(dataList, PushNotifyEnum.MEMO.getAttr(), ""));
            planAddDTO.setDataList(planDataList);
            planAddDTO.setSerialNo("");
            planAddDTO.setCorpid(formDataAddDTO.getCorpid());
            planAddDTO.setUserId(formDataAddDTO.getUserId());
            joinCommunicatePlan(planAddDTO);
        }
        // 日志
        if(Objects.nonNull(isBatch)&&Objects.equals(-1,isBatch)){
            // 更新操作不加日志
            return new BaseVO();
        }
        dynamicHelp.addPushNotify(formDataAddDTO,oldDataList,linkBusinessType);
        PushNotifyLogHandle pushNotufyLogHandle = operationLogFactory.getPushNotufyLogHandle(SaasMarkEnum.SAAS.getCode(),
                redundantTemplateTypeEnum.getCode());
        // 走新的日志处理 本次只改造crm的
        if(Objects.nonNull(pushNotufyLogHandle)){
            operationLogHelp.addPushNotifyLog(formDataAddDTO,oldDataList,redundantTemplateTypeEnum);
            return new BaseVO();
        }


        String loginUserName = formDataAddDTO.getLoginUserName();
        // 关联数据名称
        JSONArray jsonArray = new JSONArray();
        StringBuffer linkNameBuffer = new StringBuffer();
        JSONArray nameArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(oldDataList, PushNotifyEnum.NOTIFY_NAME.getAttr(), jsonArray);
        for (Object object : nameArr) {
            JSONObject jsonObject = JsonHelperUtil.parseObject(object.toString());
            String name = jsonObject.getString("name");
            if (linkNameBuffer.length() == 0) {
                linkNameBuffer.append(name);
            } else {
                linkNameBuffer.append("、").append(name);
            }
        }
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.PUSH_NOTIFY_LOG_MEMO_VALUE), loginUserName, XbbRefTypeEnum.getByCode(linkBusinessType).getName(), linkNameBuffer.toString(), FastJsonHelper.getStringOrDefaultFromFormData(dataList, PushNotifyEnum.MEMO.getAttr(), ""));
        OperateLogEntity logEntity = new OperateLogEntity(formDataAddDTO.getCorpid(), formDataAddDTO.getUserId(), loginUserName, OperateModuleTypeEnum.PUSH_NOTIFY,
        OperateTypeEnum.NEW, null, XbbRefTypeEnum.PUSH_NOTIFY.getName(), memo, formDataAddDTO.getHttpHeader(), null);
        operateLogModel.insert(logEntity);
//        opportunityOperationLogHandle.addReminder(formDataAddDTO,oldDataList,linkBusinessType);
        return new BaseVO();
    }

    @Override
    public FormDataThoroughDeleteVO thoroughDelete(FormDataThoroughDeleteDTO formDataThoroughDeleteDTO) throws XbbException {
        if (!formDataThoroughDeleteDTO.getLoginUser().isAdminOrBoss()) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100017);
        }
        FormDataThoroughDeleteVO formDataThoroughDeleteVO = new FormDataThoroughDeleteVO();
        try {
            String corpid = formDataThoroughDeleteDTO.getCorpid();
            Integer saasMark = formDataThoroughDeleteDTO.getSaasMark();
            Integer businessType = formDataThoroughDeleteDTO.getBusinessType();
            if (SaasMarkEnum.SAAS.getCode().equals(saasMark)) {
                List<Long> dataIds = formDataThoroughDeleteDTO.getDataIdList();
                IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, businessType, saasMark);
                List<String> nameList = new ArrayList<>();
                BoolQueryBuilder builder = boolQuery();
                builder.filter(termQuery("corpid.keyword", corpid));
                builder.filter(termsQuery(StringConstant.DATA_ID, dataIds));
                List<String> fieldList = new ArrayList<>();
                String attr = "";
                if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
                    fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.NAME));
                    attr = CustomerManagementEnum.NAME.getAttr();
                } else if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                    fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.COMPANY_NAME));
                    attr = CustomerManagementEnum.NAME.getAttr();
                }
                fieldList.add("formId");
                List<PaasFormDataEntityExt> entityExts = esHelper.findByScroll(indexTypeEnum, builder, PaasFormDataEntityExt.class, fieldList);
                if (CollectionsUtil.isEmpty(entityExts)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
                }
                Long formId = 0L;
                for(PaasFormDataEntityExt entityExt : entityExts){
                    formId = entityExt.getFormId();
                    JSONObject data = entityExt.getData();
                    String cusName = FastJsonHelper.getStringOrDefaultFromFormData(data, attr, "");
                    nameList.add(cusName);
                }
                if (Objects.isNull(formDataThoroughDeleteDTO.getFormId())) {
                    formDataThoroughDeleteDTO.setFormId(formId);
                }
                // 彻底删除
                if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
                    customerModel.thoroughDeleteBatch(formDataThoroughDeleteDTO.getDataIdList(), corpid, DelEnum.REMOVE_COMPLETELY.getDel());
                    // 释放精线索用量
                    releaseFineClue(formDataThoroughDeleteDTO);
                    // 市场活动统计中间表
                    marketActivityForStaticHelp.deleteBatchMarketActivity(formDataThoroughDeleteDTO.getDataIdList(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT, corpid, BasicConstant.THREE);
                   // 删除客户动态日志
                    // DynamicStrategy dynamicStrategy = dynamicStrategyFactory.getDynamicStrategy(ProjectLogEnum.CUSTOMER_DELETE.getSubType());
                    // dynamicStrategy.throughDelete(new DynamicThroughDeleteDTO(formDataThoroughDeleteDTO));

                    customerService.deleteCustomerCommunicate(formDataThoroughDeleteDTO, formDataThoroughDeleteDTO.getDataIdList());
                } else if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                    List<Long> clueIds = formDataThoroughDeleteDTO.getDataIdList();
                    clueModel.thoroughDeleteBatch(clueIds, corpid, DelEnum.REMOVE_COMPLETELY.getDel());
                    // 释放精线索用量
                    releaseFineClue(formDataThoroughDeleteDTO);
                    customerService.deleteCustomerCommunicate(formDataThoroughDeleteDTO, formDataThoroughDeleteDTO.getDataIdList());
                    marketActivityForStaticHelp.deleteBatchMarketActivity(formDataThoroughDeleteDTO.getDataIdList(), XbbRefTypeEnum.CLUE, corpid, BasicConstant.THREE);
                    // 并且将客户中所存的该线索id和名字去掉

                    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                    BoolQueryBuilder boolQueryBuilder = boolQuery();
                    boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
                    boolQueryBuilder.filter(termsQuery(StringConstant.DEL, Arrays.asList(DelEnum.NORMAL.getDel(), DelEnum.DELETE.getDel())));
                    IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
                    boolQueryBuilder.filter(termsQuery(CustomerManagementEnum.getEsAttr4Keyword(CustomerManagementEnum.CLUE_ID), clueIds));
                    boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, customerIndex.getType()));
                    sourceBuilder.query(boolQueryBuilder);
                    PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, SizeConstant.PAGE_SIZE);

                    SearchRequest searchRequest = new SearchRequest(customerIndex.getIndex());
                    searchRequest.source(sourceBuilder);
                    XbbAggregatedPage<CustomerEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest,searchRequest, CustomerEntityExt.class);
                    if (esEntities == null) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                    }
                    List<CustomerEntityExt> resultList = new ArrayList<>(esEntities.getContent());

                    List<CustomerEntityExt> needUpdates = new ArrayList<>();
                    for (CustomerEntityExt entityExt : resultList) {
                        JSONObject data = entityExt.getData();
                        JSONArray clueIdList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, CustomerManagementEnum.CLUE_ID.getAttr(), new JSONArray());
                        if (clueIdList.isEmpty()) {
                            continue;
                        }
                        List<String> clueIdCopy = new ArrayList<>();
                        clueIds.forEach(item -> clueIdCopy.add(item.toString()));
                        clueIdCopy.removeIf(item -> !clueIdList.contains(item));
                        int i = 1;
                        boolean needRemove = false;
                        Iterator<Object> iterator = clueIdList.iterator();
                        while (iterator.hasNext()) {
                            String clue = iterator.next().toString();
                            if (clueIdCopy.contains(clue)) {
                                iterator.remove();
                                needRemove = true;
                                break;
                            }
                            i++;
                        }
                        if (needRemove) {
                            JSONArray clueNames = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, CustomerManagementEnum.CLUE_NAME_ID.getAttr(), new JSONArray());
                            Iterator<Object> nameIterate = clueNames.iterator();
                            int j = 1;
                            List<String> names = new ArrayList<>();
                            while (nameIterate.hasNext()) {
                                String nameStr = nameIterate.next().toString();
                                if (i != j) {
                                    names.add(nameStr);
                                }
                                j++;
                            }
                            data.put(CustomerManagementEnum.CLUE_ID.getAttr(), clueIdList);
                            data.put(CustomerManagementEnum.CLUE_NAME_ID.getAttr(), names);
                            needUpdates.add(entityExt);
                        }
                    }
                    if (CollectionsUtil.isNotEmpty(needUpdates)) {
                        for (CustomerEntityExt entityExt : needUpdates) {
                            // 因为一条线索只能对应一个客户，所以这边放在循环里
                            customerModel.update(entityExt);
                        }
                    }
                }
                //富文本单独处理
                richTextService.operateBatch(new FormRichTextBatchDTO(corpid, formId, businessType, saasMark, dataIds, DelEnum.DELETE.getDel(), DelEnum.REMOVE_COMPLETELY.getDel()));
                PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(entityExts.get(0).getFormId(), corpid);
                if (Objects.isNull(paasFormEntityExt)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                String userId = formDataThoroughDeleteDTO.getUserId();
                String userName = formDataThoroughDeleteDTO.getLoginUserName();
                // 日志
                OperateTypeEnum operateTypeEnum = OperateTypeEnum.COMPLETELY_DELETE;
                String nameStr = StringUtils.join(nameList, "，");
                if(Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())){
                    // 客户走新的
                    ThoroughDeleteLogDTO thoroughDeleteLogDTO = new ThoroughDeleteLogDTO(formDataThoroughDeleteDTO,nameStr);
                    customerOperationLogHandle.thoroughDelete(thoroughDeleteLogDTO);
                }else{
                    if(dataIds.size() > 1 ){
                        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_COMPLETELY_DELETE_FORM_DETAIL), userName, paasFormEntityExt.getName(), dataIds.size());
                        List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        InfoArrPojo infoArrPojo = new InfoArrPojo();
                        infoArrPojo.setTitle(paasFormEntityExt.getName());
                        infoArrPojo.setContent(nameStr);
                        infoArrPojoList.add(infoArrPojo);
                        mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM_DATA, operateTypeEnum,
                                "", "", memo, formDataThoroughDeleteDTO.getHttpHeader());
                    } else if (Objects.equals(dataIds.size(), 1)){
                        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_COMPLETELY_DELETE_WORK), userName, paasFormEntityExt.getName(), nameStr);
                        mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM_DATA, operateTypeEnum,
                                dataIds.get(0).toString(), nameStr, memo, formDataThoroughDeleteDTO.getHttpHeader());
                    }
                }
            } else {

                paasFormDataModel.thoroughDeleteBatch(formDataThoroughDeleteDTO.getDataIdList(), corpid, DelEnum.REMOVE_COMPLETELY.getDel());
                //富文本单独处理
                richTextService.operateBatch(new FormRichTextBatchDTO(corpid, formDataThoroughDeleteDTO.getFormId(), businessType,
                        saasMark, formDataThoroughDeleteDTO.getDataIdList(), DelEnum.DELETE.getDel(), DelEnum.REMOVE_COMPLETELY.getDel()));
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormData.restore数据还原出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formDataThoroughDeleteVO;
    }
    /**
     * 推送提醒保存校验
     *
     * @param formDataAddDTO 入参
     * @throws XbbException 异常
     */
    private Integer notifyBeforeSave(FormDataAddDTO formDataAddDTO) throws XbbException {
        JSONObject dataList = formDataAddDTO.getDataList();
        JSONArray jsonArray = new JSONArray();
        JSONArray nameArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataList, PushNotifyEnum.NOTIFY_NAME.getAttr(), jsonArray);
        if (nameArr.isEmpty()) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, ErrorMessageConstant.PLEASE_SELECT_NOTIFY_PERSON);
        }
        JSONObject nameObj = nameArr.getJSONObject(BasicConstant.ZERO);
        Integer linkBusinessType = nameObj.getInteger(StringConstant.BUSINESS_TYPE);
        saasSaveHelp.formatLinkBusiness4Save(dataList, PushNotifyEnum.NOTIFY_NAME.getAttr(), PushNotifyEnum.NOTIFY_NAME_LINKED_TEXT.getAttr(), PushNotifyEnum.NOTIFY_NAME.getFieldType());
        JSONArray notifyName = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataList, PushNotifyEnum.NOTIFY_NAME.getAttr(), jsonArray);
        List<Long> notifyNameIdList = notifyName.toJavaList(Long.class);

        JSONArray executorArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataList, PushNotifyEnum.EXECUTOR.getAttr(), jsonArray);
        JSONArray customArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(dataList, PushNotifyEnum.EXECUTOR_LINKED_TEXT.getAttr(), jsonArray);
        if (executorArr.isEmpty() && customArr.isEmpty()) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, ErrorMessageConstant.PLEASE_SELECT, PushNotifyEnum.EXECUTOR.getAttrName());
        }
        Long communicateTime = FastJsonHelper.getLongOrDefaultFromFormData(dataList, PushNotifyEnum.COMMUNICATE_TIME.getAttr(), 0L);
        JSONObject notifyTypeObj = FastJsonHelper.getJsonObjectOrDefaultFromFormData(dataList, PushNotifyEnum.NOTIFY_TYPE.getAttr(), new JSONObject());
        String notifyTypeStr = notifyTypeObj.getString(StringConstant.VALUE);
        Integer notifyType = StringUtil.toInt(notifyTypeStr, BasicConstant.ZERO);
        dataList.put(PushNotifyEnum.NOTIFY_TYPE.getAttr(), notifyType.toString());
        Long notifyTime = FastJsonHelper.getLongFromFormData(dataList, PushNotifyEnum.NOTIFY_TIME.getAttr());
        CommunicatePlanNotifyTypeEnum communicatePlanNotifyTypeEnum = CommunicatePlanNotifyTypeEnum.getByCode(notifyType);
        switch (communicatePlanNotifyTypeEnum) {
            case ADVANCE_ONE_QUARTER_HOUR:
                notifyTime = communicateTime - TimeConstant.QUARTER_DURATION;
                break;
            case ADVANCE_ONE_HOUR:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_HOUR;
                break;
            case ADVANCE_ONE_DAY:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_DAY;
                break;
            case ADVANCE_THREE_DAY:
                notifyTime = communicateTime - TimeConstant.SECONDS_THREE_DAY;
                break;
            case ADVANCE_ONE_WEEK:
                notifyTime = communicateTime - TimeConstant.SECONDS_PER_WEEK;
                break;
            case CUSTOM_TIME:
                if (notifyTime == null) {
                    notifyTime = communicateTime;
                }
                break;
            case UNKNOW:
            default:
                throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
        }
        if (DateUtil.getInt() > notifyTime) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, ErrorMessageConstant.TIME_MUST_BEYOND_NOW);
        }
        String notifyTimeStr = DateTimeUtil.getString(notifyTime, DateTimeUtil.SDFYMDHM);
        String communicateStr = DateTimeUtil.getString(communicateTime, DateTimeUtil.SDFYMDHM);
        // 19189 【成功部】跟进提醒自定义提醒时间在跟进时间之后无法保存
       /* if (!Objects.equals(notifyTimeStr, communicateStr) && notifyTime > communicateTime) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, ErrorMessageConstant.NOTIFY_TIME_MUST_BEYOND_COMMUNICATE);
        }*/
        dataList.put(PushNotifyEnum.NOTIFY_TIME.getAttr(), notifyTime);
        JSONObject repeatNotifyObj = FastJsonHelper.getJsonObjectOrDefaultFromFormData(dataList, PushNotifyEnum.REPEAT_NOTIFY.getAttr(), new JSONObject());
        Integer repeatNotify = StringUtil.toInt(repeatNotifyObj.getString(StringConstant.VALUE), BasicConstant.ZERO);
        // 枚举和下拉项不一致，需要-1
        TimeIntervalTypeEnum timeEnum = TimeIntervalTypeEnum.getByCode(repeatNotify - 1);
        String loopNumStr = FastJsonHelper.getStringOrDefaultFromFormData(dataList, PushNotifyEnum.LOOP_NUM.getAttr(), "");
        if (!Objects.equals(repeatNotify, 1)) {
            //判断循环次数是否为整数
            if(!RegexUtil.isTwoPositiveInt(loopNumStr)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, MessageConstant.LOOP_NUM);
            }
        }
        List<Long> notifyTimeList = new ArrayList<>();
        Integer loopNum = StringUtil.toInt(loopNumStr, 0);
        switch (timeEnum) {
            case NO_LOOP:
                notifyTimeList.add(notifyTime);
                break;
            case DAY:
                for (int i = 0; i < loopNum; i++) {
                    notifyTimeList.add(notifyTime);
                    notifyTime += TimeConstant.SECONDS_PER_DAY;
                }
                break;
            case WEEK:
                for (int i = 0; i < loopNum; i++) {
                    notifyTimeList.add(notifyTime);
                    notifyTime += TimeConstant.SECONDS_PER_WEEK;
                }
                break;
            case MONTH:
                Calendar calendarMonth = Calendar.getInstance();
                calendarMonth.setTime(new Date(notifyTime * 1000L));
                for (int i = 0; i < loopNum; i++) {
                    notifyTimeList.add((calendarMonth.getTimeInMillis()) / 1000L);
                    // 本月到下个月的今天的时间 S
                    calendarMonth.add(Calendar.MONTH, 1);
                }
                break;
            case YEAR:
                Calendar calendarYear = Calendar.getInstance();
                calendarYear.setTime(new Date(notifyTime * 1000L));
                for (int i = 0; i < loopNum; i++) {
                    notifyTimeList.add((calendarYear.getTimeInMillis()) / 1000L);
                    // 今年到明年的时间 S S
                    calendarYear.add(Calendar.YEAR, 1);
                }
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, ErrorMessageConstant.REPEAT_SELECT_ERROR);
        }
        String corpid = formDataAddDTO.getCorpid();
        Map<Long, List<String>> pushUserIdMap = getPushMap(executorArr, customArr, linkBusinessType, corpid, notifyNameIdList);
        Map<Long, String> pushTitleMap = getPushTitleMap(linkBusinessType, notifyNameIdList, corpid);
        savePush(formDataAddDTO, notifyNameIdList, pushTitleMap, pushUserIdMap, linkBusinessType, corpid, notifyTimeList);
        return linkBusinessType;
    }

    /**
     * 保存推送提醒
     *
     * @param formDataAddDTO 数据
     * @param notifyNameIdList ids
     * @param pushTitleMap 标题
     * @param pushUserIdMap 推送人员
     * @param linkBusinessType 类型
     * @param corpid 公司id
     * @param notifyTimeList 集合
     * @throws XbbException 异常
     */
    private void savePush(FormDataAddDTO formDataAddDTO, List<Long> notifyNameIdList, Map<Long,String> pushTitleMap, Map<Long,List<String>> pushUserIdMap, Integer linkBusinessType, String corpid, List<Long> notifyTimeList) throws XbbException{
        JSONObject dataList = formDataAddDTO.getDataList();
        String title = FastJsonHelper.getStringOrDefaultFromFormData(dataList, PushNotifyEnum.TITLE.getAttr(), "");
        title = StringUtil.filterEmoji(title);
        String content = FastJsonHelper.getStringOrDefaultFromFormData(dataList, PushNotifyEnum.MEMO.getAttr(), "");
        content = StringUtil.filterEmoji(content);
        List<String> userIdList;
        if (!notifyNameIdList.isEmpty()) {
            Long linkId = notifyNameIdList.get(0);
            PaasFormDataEntityExt paasFormDataEntityExt = proGetHelp.getByKey(linkId, linkBusinessType, formDataAddDTO.getSaasMark(), corpid);
            if (paasFormDataEntityExt == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
            } else if (Objects.equals(paasFormDataEntityExt.getDel(), DelEnum.DELETE.getDel())) {
                if (linkBusinessType != null && !Objects.equals(linkBusinessType, XbbRefTypeEnum.CUSTOMER_RECYCLE.getCode()) && !Objects.equals(linkBusinessType, XbbRefTypeEnum.CLUE_RECYCLE.getCode())) {
                    // 客户回收站的客户del为1
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
                }
            }
            // 跳对应业务详情需要其对应的appId，menuId,formId
            formDataAddDTO.setAppId(paasFormDataEntityExt.getAppId());
            formDataAddDTO.setMenuId(paasFormDataEntityExt.getMenuId());
            formDataAddDTO.setFormId(paasFormDataEntityExt.getFormId());
        }
        for (Long refId : notifyNameIdList) {
            title = notifyNameIdList.size() != BasicConstant.ONE ? pushTitleMap.get(refId) : title;
            for(Long notifyTime2 : notifyTimeList){
                userIdList = pushUserIdMap.get(refId);

                XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(linkBusinessType);
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(formDataAddDTO.getAppId(), formDataAddDTO.getMenuId(), formDataAddDTO.getFormId(), refId, SaasMarkEnum.SAAS.getCode(), linkBusinessType);

                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, userIdList, Collections.singletonList(refId), 1, notifyTime2, title, content, null, options);
                try {
                    switch (xbbRefTypeEnum) {
                        case CUSTOMER_MANAGEMENT:
                        case COMMUNICATE_PLAN:
                            messageService.insertPushData(messageRabbitMqDTO, PushTypeEnum.CUSTOMER_PUSH);
                            break;
                        case CONTRACT:
                            messageService.insertPushData(messageRabbitMqDTO, PushTypeEnum.CONTRACT_PUSH);
                            break;
                        case SALES_OPPORTUNITY:
                            messageService.insertPushData(messageRabbitMqDTO, PushTypeEnum.OPPORTUNITY_PUSH);
                            break;
                        case CONTACT:
                            messageService.insertPushData(messageRabbitMqDTO, PushTypeEnum.CONTACT_PUSH);
                            break;
                        case SUPPLIER:
                            // 供应商的跟进提醒 落地页为供应商详情页
                            messageService.insertPushData(messageRabbitMqDTO, PushTypeEnum.SUPPLIER_PUSH);
                            break;
                        case PURCHASE:
                            //采购合同的跟进提醒 落地页为采购合同详情页
                            messageService.insertPushData(messageRabbitMqDTO, PushTypeEnum.PURCHASE_PUSH);
                            break;
                        case QUOTATION:
                            messageService.insertPushData(messageRabbitMqDTO, PushTypeEnum.QUOTATION_PUSH);
                            break;
                        case CLUE:
                            messageService.insertPushData(messageRabbitMqDTO, PushTypeEnum.CLUE_PUSH);
                            break;
                        default:
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
                    }
                } catch (XbbException e) {
                    LOG.error("ListBatchServiceImpl.savePush() insertPushData出错", e);
                }

            }
        }

    }

    /**
     * 获取推送标题
     *
     * @param linkBusinessType 类型
     * @param notifyNameIdList id
     * @param corpid 公司id
     * @return 标题map
     * @throws XbbException 异常
     */
    private Map<Long,String> getPushTitleMap(Integer linkBusinessType, List<Long> notifyNameIdList, String corpid) throws XbbException{
        Map<Long,String> pushTitleMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.ID_IN, notifyNameIdList);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, linkBusinessType, SaasMarkEnum.SAAS.getCode());
        List<PaasFormDataEntityExt> paasFormDataEntityExts = paasEsModel.selectByCondition(linkBusinessType, new HashMap<>(BasicConstant.ONE), param, indexTypeEnum);
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(linkBusinessType);
        switch (xbbRefTypeEnum) {
            case CUSTOMER_MANAGEMENT:
            case CONTRACT:
            case SALES_OPPORTUNITY:
            case CONTACT:
            case SUPPLIER:
            case CLUE:
                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                    Long id = paasFormDataEntityExt.getId();
                    String pushTitle = FastJsonHelper.getStringOrDefaultFromFormData(paasFormDataEntityExt.getData(), CustomerManagementEnum.NAME.getAttr(), "") + I18nMessageUtil.getMessage(StringConstant.NOTIFY);
                    pushTitleMap.put(id, pushTitle);
                }
                break;
            case PURCHASE:
            case QUOTATION:
                for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataEntityExts) {
                    Long id = paasFormDataEntityExt.getId();
                    String pushTitle = paasFormDataEntityExt.getSerialNo() + I18nMessageUtil.getMessage(StringConstant.NOTIFY);
                    pushTitleMap.put(id, pushTitle);
                }
                break;
           default:
               break;
        }
        return pushTitleMap;
    }

    /**
     * 获取推送人员map
     *
     * @param executorArr 执行人
     * @param customArr 自定义人员
     * @param linkBusinessType 类型
     * @param corpid 公司id
     * @param notifyNameIdList 人员
     * @return map
     * @throws XbbException 异常
     */
    private Map<Long, List<String>> getPushMap(JSONArray executorArr, JSONArray customArr, Integer linkBusinessType, String corpid, List<Long> notifyNameIdList) throws XbbException{
        List<String> userIds = new ArrayList<>();
        if (Objects.nonNull(customArr)) {
            for(Object object: customArr) {
                JSONObject jsonObject = (JSONObject) object;
                if (Objects.nonNull(jsonObject.get(StringConstant.SAAS_LINK_BUSINESS_ID))) {
                    userIds.add(jsonObject.getString(StringConstant.SAAS_LINK_BUSINESS_ID));
                }
            }
        }
        Map<Long, List<String>> pushUserIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        boolean isManager = false;
        boolean isCooper = false;
        boolean isCustom = false;
        for (int i = 0; i < executorArr.size(); i ++) {
            JSONObject jsonObject = executorArr.getJSONObject(i);
            Integer check = Integer.parseInt(jsonObject.getString(StringConstant.VALUE));
            if (Objects.equals(check, ExecutorCheckBoxEnum.MAIN_USER_CHECK.getCode())) {
                isManager = true;
            }
            if (Objects.equals(check, ExecutorCheckBoxEnum.COOPER_USER_CHECK.getCode())) {
                isCooper = true;
            }
            if (Objects.equals(check, ExecutorCheckBoxEnum.CUSTOM_CHECK.getCode())) {
                isCustom = true;
            }
        }
        List<UserTeamEntity> userTeamEntityList = userTeamService.batchGetUserTeam(notifyNameIdList, corpid, linkBusinessType);
        List<UserTeamEntity> needPushUserList = new ArrayList<>();
        if (isManager && isCooper) {
            needPushUserList = userTeamEntityList;
        } else {
            if (isManager) {
                for (UserTeamEntity userTeamEntity : userTeamEntityList) {
                    if (Objects.equals(userTeamEntity.getIsMain(), BasicConstant.ONE)) {
                        needPushUserList.add(userTeamEntity);
                    }
                }
            }
            if (isCooper) {
                for (UserTeamEntity userTeamEntity : userTeamEntityList) {
                    if (Objects.equals(userTeamEntity.getIsMain(), BasicConstant.ZERO)) {
                        needPushUserList.add(userTeamEntity);
                    }
                }
            }
        }
        initUserIdMap(pushUserIdMap, needPushUserList);
        if (isCustom) {
            for (Long id : notifyNameIdList) {
                if (!pushUserIdMap.containsKey(id)){
                    pushUserIdMap.put(id, userIds);
                }else{
                    List<String> userIdList = pushUserIdMap.get(id);
                    userIdList.addAll(userIds);
                    pushUserIdMap.put(id, userIdList);
                }

            }
        }
        if (pushUserIdMap.isEmpty()) {
            if (isManager && isCooper) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, ErrorMessageConstant.MAIN_COPPER_NOT_EXISTS);
            } else if (isManager) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, ErrorMessageConstant.MAIN_NOT_EXISTS);
            } else if (isCooper) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002,ErrorMessageConstant.COPPER_NOT_EXISTS);
            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, ErrorMessageConstant.PLEASE_ENTER_REMINDER);
            }
        }
        return pushUserIdMap;
    }

    /**
     * 获取id集合
     *
     * @param pushUserIdMap map
     * @param needPushUserList 需要推送的人员集合
     */
    private void initUserIdMap(Map<Long,List<String>> pushUserIdMap, List<UserTeamEntity> needPushUserList) {
       if (Objects.nonNull(needPushUserList)) {
           for (UserTeamEntity entity : needPushUserList) {
               Long dataId = entity.getDataId();
               String userId = entity.getUserId();
               List<String> userIdList;
               if(!pushUserIdMap.containsKey(dataId)){
                   userIdList = new ArrayList<>();
               }else{
                   userIdList = pushUserIdMap.get(dataId);
               }
               userIdList.add(userId);
               pushUserIdMap.put(dataId, userIdList);
           }
       }
    }

    /**
     * 产品分配基本方法
     * @param corpid 公司did
     * @param productIdList 产品id
     * @return 产品名称
     * @throws XbbException
     */
    private StringBuilder portionProductName(String corpid,List<Long> productIdList) throws XbbException{
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termsQuery("data." + ProductEnum.PARENT_ID.getAttr() , productIdList));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_PRODUCT.getType()));
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PRODUCT.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, productIdList.size());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        List<PaasFormDataEntityExt> productList = esEntities.getContent();
        if (productList.isEmpty()){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        StringBuilder productNameBuilder = new StringBuilder();
        productIdList = new ArrayList<>();
        for (PaasFormDataEntityExt entity : productList){
            productIdList.add(entity.getDataId());
            StringUtil.stringBuilderAppendSuffix(productNameBuilder,"|",entity.getData().getString(ProductEnum.NAME.getAttr()));
        }
        return productNameBuilder;
    }

    private List<Long> getSubProduct(String corpid, List<Long> dataIdList) throws XbbException{
        //TODO haibin.zhang 日志
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
        boolQueryBuilder.filter(termsQuery("data." + ProductEnum.PARENT_ID.getAttr() , dataIdList));
        List<ProductEntityExt> productEntityExtList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PRODUCT,boolQueryBuilder,ProductEntityExt.class,Collections.singletonList(FieldTypeEnum.DATAID.getAlias()));
        Set<Long> childProductIdSet = new HashSet<>();
        //产品ID参数做校验
        if (CollectionsUtil.isEmpty(productEntityExtList) || productEntityExtList.size() < dataIdList.size()){
            throw new XbbException(ProductErrorCodeEnum.API_ERROR_205117);
        }
        for (ProductEntityExt entityExt : productEntityExtList){
            childProductIdSet.add(entityExt.getDataId());
        }
        return new ArrayList<>(childProductIdSet);
    }

    /**
     * 校验编辑权限
     * @param fieldAttrEntityList
     * @param formDataUpdateBatchDTO
     * @param list
     * @throws XbbException
     */
    private void checkEditPermission(List<FieldAttrEntity> fieldAttrEntityList, FormDataUpdateBatchDTO formDataUpdateBatchDTO, List<PaasFormDataEntityExt> list) throws XbbException {

        batchEditHelp.checkEditPermission(fieldAttrEntityList, formDataUpdateBatchDTO, list);
    }

    /**
     * 校验编辑权限
     *
     * @param fieldAttrEntity 字段类型
     * @param formDataUpdateBatchDTO 接口参数
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-07-03 17:30
     * @since v1.0
     * @version v1.0
     */
    private void checkEditPermission(FieldAttrEntity fieldAttrEntity, FormDataUpdateBatchDTO formDataUpdateBatchDTO, List<PaasFormDataEntityExt> list) throws XbbException {
        Integer visible = fieldAttrEntity.getVisible() != null ? fieldAttrEntity.getVisible() : BasicConstant.NO_USE;
        if (Objects.equals(BasicConstant.NO_USE, visible)) {
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260015);
        }
        Integer editable = fieldAttrEntity.getEditable() != null ? fieldAttrEntity.getEditable() : BasicConstant.NO_USE;
        if (Objects.equals(BasicConstant.NO_USE, editable)) {
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260015);
        }
        if (CollectionsUtil.isEmpty(list)) {
            return;
        }
        // 可见才允许可编辑
        if(Objects.equals(BasicConstant.IS_USE,visible) && Objects.equals(BasicConstant.IS_USE, editable)) {
            Integer visibleAdvance = fieldAttrEntity.getVisibleScopeEnable();
            Integer editAdvance = fieldAttrEntity.getEditableAdvanceEnable();
            List<Long> dataIdList = formDataUpdateBatchDTO.getDataIdList();
            String corpid = formDataUpdateBatchDTO.getCorpid();
            Integer businessType = formDataUpdateBatchDTO.getBusinessType();
            Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Boolean hasTeam = UserTeamEnum.hasTeam(businessType);
            Boolean publicFlag = false;
            if (hasTeam){
                if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
                    // 因为公海客户列表页的批量编辑，只要拿一个数据就能判断是否公海
                    Integer isPublic = getIntegerOrDefaultFromFormData(list.get(0).getData(), CustomerManagementEnum.IS_PUBLIC.getAttr(), 0);
                    publicFlag = isPublic == 1 ? true : false;
                }
                if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                    // 因为公海客户列表页的批量编辑，只要拿一个数据就能判断是否公海
                    Integer isPublic = getIntegerOrDefaultFromFormData(list.get(0).getData(), ClueEnum.IS_PUBLIC.getAttr(), 0);
                    publicFlag = isPublic == 1 ? true : false;
                }
                userTeamService.getUserIdMap(dataIdList,corpid,businessType,publicFlag,mainUserMap,coUserMap);
            } else {
                CoUserListDTO coUserListDTO = new CoUserListDTO();
                BeanUtil.copyProperties(formDataUpdateBatchDTO, coUserListDTO);
                coUserListDTO.setFormDataIdIn(dataIdList);
                coUserMap = coUserService.coUserMap(coUserListDTO);
            }
            if(Objects.equals(BasicConstant.IS_USE, visibleAdvance) || Objects.equals(BasicConstant.IS_USE, editAdvance)) {

                    List<PaasFormDataEntityExt> noEditList = new ArrayList<>();
                    List<PaasFormDataEntityExt> invisibleList = new ArrayList<>();
                    for (PaasFormDataEntityExt formData: list) {
                        // 负责人，协同人
                        List<String> mainUserList = mainUserMap.get(formData.getId());
                        List<String> coUserList = coUserMap.get(formData.getId());

                        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
                        handlerExplainDTO.setUserId(formDataUpdateBatchDTO.getUserId());
                        handlerExplainDTO.setLoginUser(formDataUpdateBatchDTO.getLoginUser());
                        handlerExplainDTO.setCreatorId(formData.getCreatorId());
                        // 设置创建人
                        if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType)) {
                            handlerExplainDTO.setCreatorId(formData.getData().getString(CustomerManagementEnum.CREATOR.getAttr()));
                        } else {
                            handlerExplainDTO.setCreatorId(formData.getCreatorId());
                        }
                        if(hasTeam) {
                            handlerExplainDTO.setOwnerId(mainUserList);
                        } else {
                            handlerExplainDTO.setOwnerId(Collections.singletonList(formData.getOwnerId()));
                        }
                        if(coUserList != null && !coUserList.isEmpty()) {
                            handlerExplainDTO.setCoUserId(coUserList);
                        }

                        VisibleRulePoJo visibleRulePojo = fieldAttrEntity.getVisibleScopeRule();
                        if(Objects.equals(BasicConstant.IS_USE, visibleAdvance) && visibleRulePojo != null) {
                              Boolean invisible =  ExplainUtil.invisibleOfScope(fieldAttrEntity, handlerExplainDTO);
                              if (invisible) {
                                  invisibleList.add(formData);
                            }
                        }
                        VisibleRulePoJo editRulePojo = fieldAttrEntity.getEditableRule();
                        if(Objects.equals(BasicConstant.IS_USE, editAdvance) && editRulePojo != null) {
                            Integer editType = editRulePojo.getType();
                            VisibleTypeEnum editTypeEnum = VisibleTypeEnum.getByType(editType);
                            switch (editTypeEnum) {
                                case NOT_SHOW_ANYONE:
                                    if(ExplainUtil.notShowAnyOne(editRulePojo, handlerExplainDTO)) {
                                        noEditList.add(formData);
                                    }
                                    break;
                                case SOME_PEOPLE_CAN_SEE:
                                    if(ExplainUtil.fieldCanSee(editRulePojo, handlerExplainDTO)) {
                                        noEditList.add(formData);
                                    }
                                    break;
                                default:
                                    break;
                            }
                        }
                }
                if(!invisibleList.isEmpty()) {
                    // 错误信息
                    throw new XbbException(ProErrorCodeEnum.API_ERROR_500018, String.format(ProErrorCodeEnum.API_ERROR_500018.getMsg(), invisibleList.size()));
                }
                if(!noEditList.isEmpty()) {
                    // 错误信息
                    throw new XbbException(ProErrorCodeEnum.API_ERROR_500018, String.format(ProErrorCodeEnum.API_ERROR_500018.getMsg(), noEditList.size()));
                }
            }

        }
    }

    /**
     * 客户操作加锁，暂时只有客户捞取
     * @param userId 操作人
     * @param corpid 公司id
     * @param filePrefix 缓存前缀
     */
    private void customerOperateLocking(String userId, String corpid, String filePrefix) throws XbbException {
        String key = corpid + "_" + userId;
        Long value = paasRedisHelper.getIncrNum(filePrefix,key,RedisTimeConstant.TEN_MINUTES,1,1);
        if (value > 1L){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,"正在进行捞取操作，请稍后重试");
        }
    }

    /**
     * 客户操作去锁，暂时只有客户捞取
     * @param userId 操作人
     * @param corpid 公司id
     * @param filePrefix 缓存前缀
     */
    private void removeCustomerOperateLock(String userId, String corpid, String filePrefix) {
        String key = corpid + "_" + userId;
        paasRedisHelper.removeValue(filePrefix,key);
    }

    /**
     * 客户数据加锁
     * @param customerIdList
     * @param corpid
     */
    private List<Long> customerDataLocking(List<Long> customerIdList, String corpid) {
        Iterator<Long> iterator = customerIdList.iterator();
        List<Long> lackCustomerIdList = new ArrayList<>();
        while (iterator.hasNext()){
            Long customerId = iterator.next();
            String key = corpid + "_" + customerId;
            Long value = paasRedisHelper.getIncrNum(RedisPrefixConstant.CUSTOMER_LIST_BATCH,key,10,1,1);
            if (value > 1L){
                lackCustomerIdList.add(customerId);
                iterator.remove();
            }
        }
        return lackCustomerIdList;
    }

    /**
     * 线索数据加锁
     * @param clueIdList
     * @param corpid
     */
    private List<Long> clueDataLocking(List<Long> clueIdList, String corpid) {
        Iterator<Long> iterator = clueIdList.iterator();
        List<Long> lackCustomerIdList = new ArrayList<>();
        while (iterator.hasNext()){
            Long clueId = iterator.next();
            String key = corpid + "_" + clueId;
            Long value = paasRedisHelper.getIncrNum(RedisPrefixConstant.CLUE_LIST_BATCH,key,10,1,1);
            if (value > 1L){
                lackCustomerIdList.add(clueId);
                iterator.remove();
            }
        }
        return lackCustomerIdList;
    }

    /**
     * 线索数据加锁
     * @param clueIdList
     * @param corpid
     */
    private Set<Long> clueAutoAssignmentLocking(List<Long> clueIdList, String corpid) {
        Set<Long> value4Set = paasRedisHelper.getValue4Set(RedisPrefixConstant.CLUE_AUTO_ALLOT, corpid);
        if (CollectionsUtil.isEmpty(value4Set)) {
            value4Set = new HashSet<>();
        }
        clueIdList.removeAll(value4Set);

        return value4Set;
    }

    /**
     * 客户数据去锁
     * @param customerIdList
     * @param corpid
     */
    private void removeCustomerDataLock(List<Long> customerIdList, String corpid) {
        for (Long customerId : customerIdList){
            String key = corpid + "_" + customerId;
            paasRedisHelper.removeValue(RedisPrefixConstant.CUSTOMER_LIST_BATCH,key);
//            String value = paasRedisHelper.getValue(RedisPrefixConstant.CUSTOMER_LIST_BATCH,key);
        }

    }

    /**
     * 数据加锁
     * @param dataIdList
     * @param corpid
     */
    private List<Long> dataLocking(List<Long> dataIdList, String corpid, String redisPrefix) {
        List<Long> lackCustomerIdList = new ArrayList<>();
        if (StringUtil.isEmpty(redisPrefix)) {
            return lackCustomerIdList;
        }
        Iterator<Long> iterator = dataIdList.iterator();
        while (iterator.hasNext()){
            Long customerId = iterator.next();
            String key = corpid + "_" + customerId;
            Long value = paasRedisHelper.getIncrNum(redisPrefix,key,10,1,1);
            if (value > 1L){
                lackCustomerIdList.add(customerId);
                iterator.remove();
            }
        }
        return lackCustomerIdList;
    }

    /**
     * 数据去锁
     * @param dataIdList
     * @param corpid
     * @param redisPrefix
     * 创建时间 2020/12/8 7:15 PM
     * 修改时间 2020/12/8 7:15 PM
     * @author chy
     */
    private void removeDataLock(List<Long> dataIdList, String corpid, String redisPrefix) {
        if (StringUtil.isEmpty(redisPrefix)) {
            return;
        }
        for (Long id : dataIdList){
            String key = corpid + "_" + id;
            paasRedisHelper.removeValue(redisPrefix,key);
        }

    }


    /**
     * 设置修改后的数据以及 LogValue (解析不同的数据结构)
     * @param editedAttr2ValueMap
     * @param dummyAttr2ValueMap
     * @param explainMap
     * @param formDataUpdateBatchDTO
     * @throws XbbException
     */
    private void setBatchEditDataAndLog(Map<String, Object> editedAttr2ValueMap, Map<String, Object> dummyAttr2ValueMap, Map<String, FieldAttrEntity> explainMap, FormDataUpdateBatchDTO formDataUpdateBatchDTO) throws XbbException {
        List<AttrValuePojo> logFiledEditedList = new ArrayList<>();
        for (Map.Entry<String, Object> av : dummyAttr2ValueMap.entrySet()) {
            String attr = av.getKey();
            Object value = av.getValue();
            AttrValuePojo logPojo = getLogPojo(explainMap, attr, value);
            logFiledEditedList.add(logPojo);
        }

        List<AttrValuePojo> fieldEditedList = new ArrayList<>();
        for (Map.Entry<String, Object> entry : editedAttr2ValueMap.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            AttrValuePojo avPojo = new AttrValuePojo();
            avPojo.setAttr(key);
            avPojo.setValue(value);
            fieldEditedList.add(avPojo);
        }
        formDataUpdateBatchDTO.setLogFieldEditedList(logFiledEditedList);
        formDataUpdateBatchDTO.setFieldEditedList(fieldEditedList);
    }

    /**
     * 获取日志信息 -- 字段改变后的值
     * @param explainMap
     * @param attr
     * @param value
     * @return
     */
    private AttrValuePojo getLogPojo(Map<String, FieldAttrEntity> explainMap, String attr, Object value) {

       return updateBatchLogHelp.getLogPojo(explainMap, attr, value);
    }

    /**
     * 同步还原相关联业务
     * 业务： 跟进记录、阶段工作及反馈、销售机会、工单、开票历史、发票信息、联系人、上下级、文件柜
     * 有的没删除，不做还原操作，以后如果删除了再补上
     *
     * @param corpid
     * @param customerUpdateTimeMap
     * @return
     * @throws
     * @author xingxing.xiao
     * @date 2019/09/17 14:42
     */
    private void restoreRalationBusiness(String corpid, Map<Long, Long> customerUpdateTimeMap, CustomerRestoreBatchDTO customerRestoreBatchDTO) throws XbbException {
        // 跟进记录
        customerCommunicateService.restoreBatch(corpid, customerUpdateTimeMap, customerRestoreBatchDTO);
        // 销售机会
        opportunityService.restoreBatch(corpid, customerUpdateTimeMap, customerRestoreBatchDTO);
        // 发票信息
        invoiceService.restoreBatch(corpid, customerUpdateTimeMap, customerRestoreBatchDTO);
        // 联系人
        contactService.restoreBatch(corpid, customerUpdateTimeMap, customerRestoreBatchDTO);
        // 报价单
        quotationService.restoreBatch(corpid, customerUpdateTimeMap, customerRestoreBatchDTO);
    }

    /**
     * 分配，捞取客户的公海池规则判断
     *
     * @param corpid
     * @param dataIdList
     * @param userEntity
     * @param entityExtMap
     * @throws
     * @author long.rao
     * @date 2020-05-18 13:40
     */
    public Map<Integer, List<String>>  canGainCustomer(String corpid, List<Long> dataIdList, UserEntity userEntity, Map<Long, PaasFormDataEntityExt> entityExtMap) throws XbbException{
        Map<Integer, List<String>> errorMap = new HashMap<>(BasicConstant.ONE);
        List<CustomerRuleEntity> ruleList = new ArrayList<>();
        //公海高级模式兼容老逻辑
        publicSeniorRuleHelp.getPublicSeniorRuleList(corpid,XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(),ruleList,new ArrayList<>());
        String errorMsg = "";
        for (CustomerRuleEntity ruleEntity : ruleList) {
            if (Objects.equals(ruleEntity.getRuleType(), CustomerRuleEnum.MAX_CUSTOMER_NUM_RULE.getCode())) {
                errorMsg = userTeamService.canGainMaxNum(ruleEntity, corpid, userEntity, entityExtMap);
                if (StringUtil.isNotEmpty(errorMsg)) {
                    dataIdList.clear();
                    errorMap.put(ruleEntity.getRuleType(), new ArrayList<>());
                    break;
                }
            } else if (Objects.equals(ruleEntity.getRuleType(), CustomerRuleEnum.GAIN_RATE_RULE.getCode())) {
                errorMsg = userTeamService.canGainRate(ruleEntity, corpid, userEntity, dataIdList.size());
                if (StringUtil.isNotEmpty(errorMsg)) {
                    dataIdList.clear();
                    errorMap.put(ruleEntity.getRuleType(), new ArrayList<>());
                    break;
                }
            }
        }
        if (!errorMap.isEmpty()) {
            return errorMap;
        }
        // 因为前负责人这里会对dataIdList这里可能造成删减，所以单独判断
        for (CustomerRuleEntity ruleEntity : ruleList) {
            if (Objects.equals(ruleEntity.getRuleType(), CustomerRuleEnum.PRE_PRINCIPAL_RULE.getCode())) {
                List<String> errorName = userTeamService.canGainPrePrincipal(ruleEntity, corpid, userEntity, dataIdList, entityExtMap, OperateTypeEnum.DISTRIBUTE.getName());
                if (!errorName.isEmpty()) {
                    errorMap.put(ruleEntity.getRuleType(), errorName);
                }
            }
        }
        return errorMap;
    }

    /**
     * 分配，捞取线索的公海池规则判断
     *
     * @param corpid
     * @param dataIdList
     * @param userEntity
     * @param entityExtMap
     * @throws XbbException
     */
    public Map<Integer, List<String>>  canGainClue(String corpid, List<Long> dataIdList, UserEntity userEntity, Map<Long, PaasFormDataEntityExt> entityExtMap) throws XbbException{
        Map<Integer, List<String>> errorMap = new HashMap<>(BasicConstant.ONE);
        List<ClueRuleEntity> ruleList = new ArrayList<>();
        //公海高级模式兼容老逻辑
        publicSeniorRuleHelp.getPublicSeniorRuleList(corpid,XbbRefTypeEnum.CLUE.getCode(),new ArrayList<>(),ruleList);
        String errorMsg = "";
        for (ClueRuleEntity ruleEntity : ruleList) {
            if (Objects.equals(ruleEntity.getRuleType(), ClueRuleEnum.MAX_CLUE_NUM_RULE.getCode())) {
                errorMsg = userTeamService.canGainMaxClueNum(ruleEntity, corpid, userEntity, entityExtMap);
                if (StringUtil.isNotEmpty(errorMsg)) {
                    dataIdList.clear();
                    errorMap.put(ruleEntity.getRuleType(), new ArrayList<>());
                    break;
                }
            } else if (Objects.equals(ruleEntity.getRuleType(), ClueRuleEnum.GAIN_RATE_RULE.getCode())) {
                errorMsg = userTeamService.canGainClueRate(ruleEntity, corpid, userEntity, dataIdList.size());
                if (StringUtil.isNotEmpty(errorMsg)) {
                    dataIdList.clear();
                    errorMap.put(ruleEntity.getRuleType(), new ArrayList<>());
                    break;
                }
            }
        }
        if (!errorMap.isEmpty()) {
            return errorMap;
        }
        // 因为前负责人这里会对dataIdList这里可能造成删减，所以单独判断
        for (ClueRuleEntity ruleEntity : ruleList) {
            if (Objects.equals(ruleEntity.getRuleType(), ClueRuleEnum.PRE_PRINCIPAL_RULE.getCode())) {
                List<String> errorName = userTeamService.canGainCluePrePrincipal(ruleEntity, corpid, userEntity, dataIdList, entityExtMap, OperateTypeEnum.DISTRIBUTE.getName());
                if (!errorName.isEmpty()) {
                    errorMap.put(ruleEntity.getRuleType(), errorName);
                }
            }
        }
        return errorMap;
    }


    /**
     * 获取日志模块
     *
     * @param businessType
     * @throws
     * @author long.rao
     * @date 2020-04-07 19:36
     */
    private OperateModuleTypeEnum getOperateType(Integer businessType) throws XbbException{
        OperateModuleTypeEnum operateTypeEnum;
        XbbRefTypeEnum refTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (refTypeEnum) {
            case CUSTOMER_MANAGEMENT:
                operateTypeEnum = OperateModuleTypeEnum.CUSTOMER;
                break;
            case SALES_OPPORTUNITY:
                operateTypeEnum = OperateModuleTypeEnum.OPPORTUNITY;
                break;
            case CONTRACT:
                operateTypeEnum = OperateModuleTypeEnum.CONTRACT;
                break;
            case REFUND:
                operateTypeEnum = OperateModuleTypeEnum.REFUND;
                break;
            case QUOTATION:
                operateTypeEnum = OperateModuleTypeEnum.QUOTATION;
                break;
            case SUPPLIER:
                operateTypeEnum = OperateModuleTypeEnum.SUPPLIER;
                break;
            case PURCHASE:
                operateTypeEnum = OperateModuleTypeEnum.PURCHASE;
                break;
            case BOM_BILL:
                operateTypeEnum = OperateModuleTypeEnum.BOMBILL;
                break;
            case PRODUCTION_ORDER:
                operateTypeEnum = OperateModuleTypeEnum.PRODUCTION_ORDER;
                break;
            case RETURNED_PURCHASE:
                operateTypeEnum = OperateModuleTypeEnum.RETURN_PURCHASE;
                break;
            case ASSEMBLE:
                operateTypeEnum = OperateModuleTypeEnum.ASSEMBLE;
                break;
            case TRANSFER:
                operateTypeEnum = OperateModuleTypeEnum.TRANSFER;
                break;
            case INVENTORY:
                operateTypeEnum = OperateModuleTypeEnum.INVENTORY;
                break;
            case INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case OTHER_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
                operateTypeEnum = InstockTypeEnum.getByStockBusinessType(businessType).getOperateModuleTypeEnum();
                break;
            case OUTSTOCK:
            case CONTRACT_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
            case ORDER_OUTSTOCK:
                operateTypeEnum = OutstockTypeEnum.getByStockBusinessType(businessType).getOperateModuleTypeEnum();
                break;
            case PAAS:
                operateTypeEnum = OperateModuleTypeEnum.PAAS_FORM;
                break;
            case MARKET_ACTIVITY:
                operateTypeEnum = OperateModuleTypeEnum.MARKET_ACTIVITY;
                break;
            case COST_ADJUST:
                operateTypeEnum = OperateModuleTypeEnum.COST_ADJUST;
                break;
            case WAREHOUSE:
                operateTypeEnum = OperateModuleTypeEnum.WAREHOUSE;
                break;
            default:
                throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        return operateTypeEnum;
    }

    /**
     * 数据已有他人使用的报错信息的处理
     *
     * @param dataIds
     * @param corpid
     * @param teamBatchVO
     * @throws
     * @author long.rao
     * @date 2020-06-03 11:17
     */
    private TeamBatchPojo lackError(List<Long> dataIds, Integer dataIdSize, String corpid, TeamBatchVO teamBatchVO, String operateStr) throws XbbException {
        TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
        IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

        List<String> lackName = new ArrayList<>(dataIds.size());
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIds));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, customerIndex.getType()));
        sourceBuilder.query(boolQueryBuilder);
        List<String> fieldList = new ArrayList<>();
        fieldList.add(CustomerManagementEnum.getAttrConnectData(CustomerManagementEnum.NAME));
        String[] strings = new String[fieldList.size()];
        sourceBuilder.fetchSource(fieldList.toArray(strings),null);

        SearchRequest searchRequest = new SearchRequest(customerIndex.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, dataIds.size());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            return teamBatchPojo;
        }
        for (PaasFormDataEntityExt entityExt : esEntities.getContent()) {
            String name = FastJsonHelper.getStringOrDefaultFromFormData(entityExt.getData(), CustomerManagementEnum.NAME.getAttr(), "");
            lackName.add(name);
        }
        teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.USED_BY_OTHER));
        commonHelp.mergeFailMsg(lackName, dataIdSize, teamBatchPojo, operateStr, teamBatchVO);
        return teamBatchPojo;
    }

    /**
     * 数据已有他人使用的报错信息的处理
     *
     * @param dataIds
     * @param corpid
     * @param teamBatchVO
     * @throws
     */
    private TeamBatchPojo lackClueError(List<Long> dataIds, Integer dataIdSize, String corpid, TeamBatchVO teamBatchVO, String operateStr) throws XbbException {
        TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
        List<String> lackName = new ArrayList<>(dataIds.size());
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIds));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CLUE.getType()));
        sourceBuilder.query(boolQueryBuilder);
        List<String> fieldList = new ArrayList<>();
        fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.COMPANY_NAME));
        String[] strings = new String[fieldList.size()];
        sourceBuilder.fetchSource(fieldList.toArray(strings),null);

        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CLUE.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, dataIds.size());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            return teamBatchPojo;
        }
        for (PaasFormDataEntityExt entityExt : esEntities.getContent()) {
            String name = FastJsonHelper.getStringOrDefaultFromFormData(entityExt.getData(), ClueEnum.COMPANY_NAME.getAttr(), "");
            lackName.add(name);
        }
        teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.USED_BY_OTHER));
        commonHelp.mergeFailMsg(lackName, dataIdSize, teamBatchPojo, operateStr, teamBatchVO);
        return teamBatchPojo;
    }

    /**
     * 数据被锁的报错信息的处理
     *
     * @param dataIds
     * @param corpid
     * @param teamBatchVO
     * @throws
     */
    private TeamBatchPojo lockClueError(Set<Long> dataIds, Integer dataIdSize, String corpid, TeamBatchVO teamBatchVO, String operateStr) throws XbbException {
        TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
        List<String> lackName = new ArrayList<>(dataIds.size());
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid ));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), dataIds));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CLUE.getType()));
        sourceBuilder.query(boolQueryBuilder);
        List<String> fieldList = new ArrayList<>();
        fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.COMPANY_NAME));
        String[] strings = new String[fieldList.size()];
        sourceBuilder.fetchSource(fieldList.toArray(strings),null);

        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CLUE.getIndex());
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, dataIds.size());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        if (esEntities == null) {
            return teamBatchPojo;
        }
        for (PaasFormDataEntityExt entityExt : esEntities.getContent()) {
            String name = FastJsonHelper.getStringOrDefaultFromFormData(entityExt.getData(), ClueEnum.COMPANY_NAME.getAttr(), "");
            lackName.add(name);
        }
        teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.CLUE_AUTO_ASSIGNING));
        commonHelp.mergeFailMsg(lackName, dataIdSize, teamBatchPojo, operateStr, teamBatchVO);
        return teamBatchPojo;
    }

    /**
     * 最大公海池规则和捞取频率规则的报错信息处理
     *
     * @param dataIdSize
     * @param customerRuleErrorMap
     * @param teamBatchPojos
     * @param teamBatchVO
     * @param operateStr
     * @throws
     * @author long.rao
     * @date 2020-06-03 11:16
     */
    private void customerRuleError(Integer dataIdSize, Map<Integer, List<String>> customerRuleErrorMap, List<TeamBatchPojo> teamBatchPojos, TeamBatchVO teamBatchVO, String operateStr) {
        if (customerRuleErrorMap.isEmpty()) {
            return;
        }
        for (Map.Entry<Integer, List<String>> entry : customerRuleErrorMap.entrySet()) {
            if (Objects.equals(entry.getKey(), CustomerRuleEnum.MAX_CUSTOMER_NUM_RULE.getCode())) {
                TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
                teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.OUTNUMBER_FOR_MAX_RULE));
                mergeFailMsg(teamBatchPojo, operateStr, teamBatchVO);
                teamBatchPojos.add(teamBatchPojo);
                break;
            } else if (Objects.equals(entry.getKey(), CustomerRuleEnum.GAIN_RATE_RULE.getCode())) {
                TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
                teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.CUSTOMER_NUM_EXCEEDS_GAIN_CUSTOMER_RULE));
                mergeFailMsg(teamBatchPojo, operateStr, teamBatchVO);
                teamBatchPojos.add(teamBatchPojo);
                break;
            }
        }
    }

    /**
     * 最大公海池规则和捞取频率规则的报错信息处理
     *
     * @param clueRuleErrorMap
     * @param teamBatchPojos
     * @param teamBatchVO
     * @param operateStr
     * @throws
     */
    private void clueRuleError(Map<Integer, List<String>> clueRuleErrorMap, List<TeamBatchPojo> teamBatchPojos, TeamBatchVO teamBatchVO, String operateStr) {
        if (clueRuleErrorMap.isEmpty()) {
            return;
        }
        for (Map.Entry<Integer, List<String>> entry : clueRuleErrorMap.entrySet()) {
            if (Objects.equals(entry.getKey(), ClueRuleEnum.MAX_CLUE_NUM_RULE.getCode())) {
                TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
                teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(ListBatchConstant.OUTNUMBER_FOR_MAX_CLUE_RULE));
                mergeFailMsg(teamBatchPojo, operateStr, teamBatchVO);
                teamBatchPojos.add(teamBatchPojo);
                break;
            } else if (Objects.equals(entry.getKey(), ClueRuleEnum.GAIN_RATE_RULE.getCode())) {
                TeamBatchPojo teamBatchPojo = new TeamBatchPojo();
                teamBatchPojo.setFailMsgReason(I18nMessageUtil.getMessage(I18nMessageUtil.getMessage(ListBatchConstant.CLUE_NUM_EXCEEDS_GAIN_CLUE_RULE)));
                mergeFailMsg(teamBatchPojo, operateStr, teamBatchVO);
                teamBatchPojos.add(teamBatchPojo);
                break;
            }
        }
    }

    /**
     * 报错信息整合
     *
     * @param teamBatchPojo
     * @param operateStr
     * @param teamBatchVO
     * @throws
     * @author long.rao
     * @date 2020-06-03 11:17
     */
    private void mergeFailMsg(TeamBatchPojo teamBatchPojo, String operateStr, TeamBatchVO teamBatchVO) {
        StringBuilder msg = new StringBuilder();
        msg.append(I18nMessageUtil.getMessage(ListBatchConstant.ALL_DATA));
        msg.append(operateStr).append(I18nMessageUtil.getMessage(ListBatchConstant.FAIL));
        teamBatchVO.setResultMsg(ListBatchResultEnum.OPERATE_FAIL.getMsg());
        teamBatchVO.setResultType(ListBatchResultEnum.OPERATE_FAIL.getAlias());
        teamBatchPojo.setFailMsg(msg.toString());
    }

    /**
     * 异步处理回款单或付款单的团队
     *
     * @param corpid
     * @param businessType
     * @param dataIds
     * @throws
     * @author long.rao
     * @date 2020-06-04 14:50
     */
    private void updateSheetTeam(String corpid,Integer businessType, Set<Long> dataIds) {
        List<Integer> types = Arrays.asList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), XbbRefTypeEnum.CONTRACT.getCode(), XbbRefTypeEnum.SUPPLIER.getCode(), XbbRefTypeEnum.PURCHASE.getCode());
        if (!types.contains(businessType)) {
            return;
        }
        Runnable runnable = () -> {
            try {
                // 因为主业务团队更新es变成了不等待，所以线程这里直接等8(在正式环境上测试后评估的结果)秒再处理，防止后面查主业务团队的时候有问题
                Thread.sleep(8000);
                XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
                for (Long id : dataIds) {
                    userTeamService.updateSheetTeam(corpid, xbbRefTypeEnum, id);
                }
            } catch (XbbException e) {
                LOG.error("updateSheetTeam error",e);
            } catch (Exception e) {
                LOG.error("updateSheetTeam error",e);
            }
        };
        threadPoolBeanConfig.listBatchThreadPool().execute(runnable);
    }

    /**
     * 过滤离职人员
     *
     * @param corpid
     * @param userTeamEntities
     * @param redisPrefix
     * @author long.rao
     * @date 2020-06-18 11:04
     */
    private void filterOutDepartingUser(String corpid, List<UserTeamEntity> userTeamEntities, String redisPrefix) {
        if (CollectionsUtil.isEmpty(userTeamEntities)) {
            return;
        }
        Set<String> userIds = new HashSet<>();
        Set<Long> ids = new HashSet<>();
        for (UserTeamEntity userTeamEntity : userTeamEntities) {
            userIds.add(userTeamEntity.getUserId());
        }
        userIds = userModel.filterOutDepartingUser(userIds, corpid);
        Iterator<UserTeamEntity> iterator1 = userTeamEntities.iterator();
        while (iterator1.hasNext()) {
            UserTeamEntity userTeamEntity = iterator1.next();
            if (!userIds.contains(userTeamEntity.getUserId())) {
                ids.add(userTeamEntity.getDataId());
                iterator1.remove();
            }
        }
        // 如果有人员离职，那么去掉这条数据的锁，可能会有问题,但是目前不好判断了
        //removeDataLock(new ArrayList<>(ids), corpid, redisPrefix);
    }

    private Map<Long, String> getClueNameMap(List<Long> handoverIdSet, String corpid, Map<Long, PaasFormDataEntityExt> entityExtMap) throws XbbException{
        Map<Long,String> clueNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (handoverIdSet.isEmpty()){
            return clueNameMap;
        }
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(),handoverIdSet));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CLUE.getType()));
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, handoverIdSet.size());
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CLUE.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        for (PaasFormDataEntityExt entity : esEntities.getContent()){
            clueNameMap.put(entity.getDataId(),entity.getData().getString(ClueEnum.COMPANY_NAME.getAttr()));
            entityExtMap.put(entity.getDataId(), entity);
        }
        return clueNameMap;
    }

    /**
     * 低代码执行服务
     * @param dataIdList
     * @param saasMark
     * @param businessType
     * @param formId
     * @param corpid
     * @return void
     * @author 吴峰
     * @date 2021/3/18 20:59
     * @throws XbbException
     */
    private void lowCodeExecuteService(List<Long> dataIdList, Integer saasMark, Integer businessType, Long formId, String corpid) throws XbbException {
        try {
            LowCodeExecuteServiceDTO lowCodeExecuteServiceDTO = new LowCodeExecuteServiceDTO();
            lowCodeExecuteServiceDTO.setAlias(LowCodeExecuteServiceEnum.DELETE.name());
            lowCodeExecuteServiceDTO.setBusinessType(businessType);
            lowCodeExecuteServiceDTO.setFormId(formId);
            lowCodeExecuteServiceDTO.setDataId(dataIdList);
            lowCodeExecuteServiceDTO.setSaasMark(saasMark);
            lowCodeExecuteServiceDTO.setCorpid(corpid);
            abstractLowCodeExecuteService.execute(lowCodeExecuteServiceDTO);
        } catch (Exception e) {
            LOG.error("listBatchServiceImpl.lowCodeExecuteService fail", e);
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void batchEditAttr(FormDataUpdateBatchDTO formDataUpdateBatchDTO, XbbRefTypeEnum xbbRefTypeEnum) throws XbbException {
        try {
            List<DataInfoDTO> dataInfoDTOs = new ArrayList<>();
            Long formId = formDataUpdateBatchDTO.getFormId();
            FormDataUpdateBatchVO formDataUpdateBatchVO = new FormDataUpdateBatchVO();
            List<Long> dataIdList = formDataUpdateBatchDTO.getDataIdList();
            for (Long dataId : dataIdList) {
                dataInfoDTOs.add(new DataInfoDTO(SaasMarkEnum.SAAS.getCode(), formId, dataId));
            }

            switch (xbbRefTypeEnum) {
                case CONTRACT:
                case ORDER:
                    ContractEditAttrUpdateDTO contractEditAttrUpdateDTO = new ContractEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, contractEditAttrUpdateDTO);
                    ContractEditAttrUpdateVO contractEditAttrUpdateVO = contractService.batchEditAttr(contractEditAttrUpdateDTO);
                    formDataUpdateBatchVO.setUpdateIdList(contractEditAttrUpdateVO.getUpdateIdList());
                    break;
                case CUSTOMER_MANAGEMENT:
                    CustomerEditAttrUpdateDTO customerEditAttrUpdateDTO = new CustomerEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, customerEditAttrUpdateDTO);
                    CustomerEditAttrUpdateVO customerEditAttrUpdateVO = customerService.batchEditAttr(customerEditAttrUpdateDTO);
                    formDataUpdateBatchVO.setUpdateIdList(customerEditAttrUpdateVO.getUpdateIdList());
                    break;
                case CONTACT:
                    ContactEditAttrUpdateDTO contactEditAttrUpdateDTO = new ContactEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, contactEditAttrUpdateDTO);
                    contactService.batchEditAttr(contactEditAttrUpdateDTO);
                    break;
                case DISTRIBUTOR_CONTACT:
                    DistributorContactEditAttrUpdateDTO distributorContactEditAttrUpdateDTO = new DistributorContactEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, distributorContactEditAttrUpdateDTO);
                    distributorContactService.batchEditAttr(distributorContactEditAttrUpdateDTO);
                    break;
                case PRODUCT:
                    ProductEditAttrUpdateDTO productEditAttrUpdateDTO = new ProductEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, productEditAttrUpdateDTO);
                    productService.batchEditAttr(productEditAttrUpdateDTO);
                    break;
                case SUPPLIER:
                    SupplierEditAttrUpdateDTO supplierEditAttrUpdateDTO = new SupplierEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, supplierEditAttrUpdateDTO);
                    supplierService.batchEditAttr(supplierEditAttrUpdateDTO);
                    break;
                case SALES_OPPORTUNITY:
                    OpportunityEditAttrUpdateDTO opportunityEditAttrUpdateDTO = new OpportunityEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, opportunityEditAttrUpdateDTO);
                    opportunityService.batchEditAttr(opportunityEditAttrUpdateDTO);
                    break;
                case TRANSFER:
                    TransferEditAttrUpdateDTO transferDeleteBatchDTO = new TransferEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, transferDeleteBatchDTO);
                    transferService.batchEditAttr(transferDeleteBatchDTO);
                    break;
                case INVENTORY:
                    InventoryEditAttrUpdateDTO inventoryEditAttrUpdateDTO = new InventoryEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, inventoryEditAttrUpdateDTO);
                    inventoryService.batchEditAttr(inventoryEditAttrUpdateDTO);
                    break;
                case OUTSTOCK:
                case CONTRACT_OUTSTOCK:
                case RETURNED_PURCHASE_OUTSTOCK:
                case OTHER_OUTSTOCK:
                case PRODUCTION_MATERIEL_OUTSTOCK:
                case WORK_ORDER_OUTSTOCK:
                    OutstockEditAttrUpdateDTO outstockEditAttrUpdateDTO = new OutstockEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, outstockEditAttrUpdateDTO);
                    outstockService.batchEditAttr(outstockEditAttrUpdateDTO);
                    break;
                case INSTOCK:
                case PURCHASE_INSTOCK:
                case REFUND_INSTOCK:
                case OTHER_INSTOCK:
                case PRODUCTION_INSTOCK:
                case RETURNED_MATERIEL_INSTOCK:
                    InstockEditAttrUpdateDTO instockEditAttrUpdateDTO = new InstockEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, instockEditAttrUpdateDTO);
                    instockService.batchEditAttr(instockEditAttrUpdateDTO);
                    break;
                case ASSEMBLE:
                    AssembleEditAttrUpdateDTO assembleEditAttrUpdateDTO = new AssembleEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, assembleEditAttrUpdateDTO);
                    assembleService.batchEditAttr(assembleEditAttrUpdateDTO);
                    break;
                case PAY_PLAN:
                    PayPlanEditAttrUpdateDTO payPlanEditAttrUpdateDTO = new PayPlanEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, payPlanEditAttrUpdateDTO);
                    payPlanService.batchEditAttr(payPlanEditAttrUpdateDTO);
                    break;
                case PAYMENT:
                    PaymentEditAttrUpdateDTO paymentEditAttrUpdateDTO = new PaymentEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, paymentEditAttrUpdateDTO);
                    paymentService.batchEditAttr(paymentEditAttrUpdateDTO);
                    break;
                case PRODUCTION_ORDER:
                    ProductionOrderEditAttrUpdateDTO productionOrderEditAttrUpdateDTO = new ProductionOrderEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, productionOrderEditAttrUpdateDTO);
                    productionOrderService.batchEditAttr(productionOrderEditAttrUpdateDTO);
                    break;
                case BOM_BILL:
                    BomEditAttrUpdateDTO bomEditAttrUpdateDTO = new BomEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, bomEditAttrUpdateDTO);
                    bomBillService.batchEditAttr(bomEditAttrUpdateDTO);
                    break;
                case PURCHASE:
                    PurchaseEditAttrUpdateDTO purchaseEditAttrUpdateDTO = new PurchaseEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, purchaseEditAttrUpdateDTO);
                    purchaseService.batchEditAttr(purchaseEditAttrUpdateDTO);
                    break;
                case RETURNED_PURCHASE:
                    ReturnedPurchaseEditAttrUpdateDTO returnedPurchaseEditAttrUpdateDTO = new ReturnedPurchaseEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, returnedPurchaseEditAttrUpdateDTO);
                    returnedPurchaseService.batchEditAttr(returnedPurchaseEditAttrUpdateDTO);
                    break;
                case INVOICE:
                    InvoiceEditAttrUpdateDTO invoiceEditAttrUpdateDTO = new InvoiceEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, invoiceEditAttrUpdateDTO);
                    invoiceService.batchEditAttr(invoiceEditAttrUpdateDTO);
                    break;
                case PURCHASE_INVOICE:
                    PurchaseInvoiceEditAttrUpdateDTO purchaseInvoiceEditAttrUpdateDTO = new PurchaseInvoiceEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO,purchaseInvoiceEditAttrUpdateDTO);
                    purchaseInvoiceService.batchEditAttr(purchaseInvoiceEditAttrUpdateDTO);
                    break;
                case SUPPLIER_CONTACT:
                    // 供应商联系人
                    SupplierContactEditAttrUpdateDTO supplierContactEditAttrUpdateDTO = new SupplierContactEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, supplierContactEditAttrUpdateDTO);
                    supplierContactService.batchEditAttr(supplierContactEditAttrUpdateDTO);
                    break;
                case WORK_ORDER:
                    WorkOrderEditAttrUpdateDTO workOrderEditAttrUpdateDTO = new WorkOrderEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, workOrderEditAttrUpdateDTO);
                    workOrderService.batchEditAttr(workOrderEditAttrUpdateDTO);
                    break;
                case REFUND:
                    RefundEditAttrUpdateDTO refundEditAttrUpdateDTO = new RefundEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, refundEditAttrUpdateDTO);
                    refundService.batchEditAttr(refundEditAttrUpdateDTO);
                    break;
                case RETURN:
                    ReturnEditAttrUpdateDTO returnEditAttrUpdateDTO = new ReturnEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, returnEditAttrUpdateDTO);
                    returnService.batchEditAttr(returnEditAttrUpdateDTO);
                    break;
                case QUOTATION:
                    QuotationEditAttrUpdateDTO quotationEditAttrUpdateDTO = new QuotationEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, quotationEditAttrUpdateDTO);
                    quotationService.batchEditAttr(quotationEditAttrUpdateDTO);
                    break;
                case PAYMENT_SHEET:
                    PaymentSheetEditAttrUpdateDTO paymentSheetEditAttrUpdateDTO = new PaymentSheetEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, paymentSheetEditAttrUpdateDTO);
                    paymentSheetService.batchEditAttr(paymentSheetEditAttrUpdateDTO);
                    break;
                case PAY_SHEET:
                    PaySheetEditAttrUpdateDTO paySheetEditAttrUpdateDTO = new PaySheetEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, paySheetEditAttrUpdateDTO);
                    payPlanSheetService.batchEditAttr(paySheetEditAttrUpdateDTO);
                    break;
                case MARKET_ACTIVITY:
                    MarketActivityEditAttrUpdateDTO marketActivityEditAttrUpdateDTO = new MarketActivityEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, marketActivityEditAttrUpdateDTO);
                    marketActivityService.batchEditAttr(marketActivityEditAttrUpdateDTO);
                    break;
                case CLUE:
                    CustomerEditAttrUpdateDTO clueEditAttrUpdateDTO = new CustomerEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, clueEditAttrUpdateDTO);
                    CustomerEditAttrUpdateVO clueEditAttrUpdateVO = clueService.batchEditAttr(clueEditAttrUpdateDTO);
                    formDataUpdateBatchVO.setUpdateIdList(clueEditAttrUpdateVO.getUpdateIdList());
                    //发送评分计算消息(批量)
                    List<String> attrList = ProSaveHelp.getAttrList(clueEditAttrUpdateDTO.getFieldEditedList());
                    if (scoreCalculateHelp.isTriggerScoreForQuickEdit(attrList, clueEditAttrUpdateDTO.getCorpid(), formId)) {
                        // scoreCallBackHelper.batchSendScoreMessage(formDataUpdateBatchDTO.getCorpid(),XbbRefTypeEnum.CLUE.getCode(),dataIdList);
                        //评分计算
                        try {
                            String dataCorpid = formDataUpdateBatchDTO.getCorpid();
                            Map<String,Object> param = new HashMap<>(4);
                            param.put("corpid",dataCorpid);
                            param.put("idIn",dataIdList);
                            param.put("del",0);
                            List clueModelEntitys = clueModel.findEntitys(param);
                            scoreCalculateService.batchDataScoreUpdate(formDataUpdateBatchDTO.getCorpid(),XbbRefTypeEnum.CLUE,clueModelEntitys);
                        }catch (Exception e){
                            LOG.error("batchEditAttr 批量评分计算失败");
                        }
                    }
                    break;
                case WAREHOUSE:
                    WareHouseEditAttrUpdateDTO wareHouseEditAttrUpdateDTO = new WareHouseEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, wareHouseEditAttrUpdateDTO);
                    warehouseService.batchEditAttr(wareHouseEditAttrUpdateDTO);
                    break;
                case OTHER_INCOME:
                    OtherIncomeEditAttrUpdateDTO otherIncomeEditAttrUpdateDTO = new OtherIncomeEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, otherIncomeEditAttrUpdateDTO);
                    otherIncomeService.batchEditAttr(otherIncomeEditAttrUpdateDTO);
                    break;
                case OTHER_EXPENSE:
                    OtherExpenseEditAttrUpdateDTO otherExpenseEditAttrUpdateDTO = new OtherExpenseEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, otherExpenseEditAttrUpdateDTO);
                    otherExpenseService.batchEditAttr(otherExpenseEditAttrUpdateDTO);
                    break;
                case FUND_TRANSFER:
                    FundTransferEditAttrUpdateDTO fundTransferEditAttrUpdateDTO = new FundTransferEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, fundTransferEditAttrUpdateDTO);
                    fundTransferService.batchEditAttr(fundTransferEditAttrUpdateDTO);
                    break;
                case DISTRIBUTOR_MANAGEMENT:
                    DistributorEditAttrUpdateDTO distributorEditAttrUpdateDTO = new DistributorEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, distributorEditAttrUpdateDTO);
                    DistributorEditAttrUpdateVO distributorEditAttrUpdateVO = distributorManageService.batchEditAttr(distributorEditAttrUpdateDTO);
                    formDataUpdateBatchVO.setUpdateIdList(distributorEditAttrUpdateVO.getUpdateIdList());
                    break;
                case DISTRIBUTOR_ACCOUNT:
                    distributorEditAttrUpdateDTO = new DistributorEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, distributorEditAttrUpdateDTO);
                    distributorAccountService.batchEditAttr(distributorEditAttrUpdateDTO);
                    break;
                case ORDER_OUTSTOCK:
                    DistributorContractOutStockEditAttrUpdateDTO distributorContractOutStockEditAttrUpdateDTO = new DistributorContractOutStockEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, distributorContractOutStockEditAttrUpdateDTO);
                    orderOutstockService.batchEditAttr(distributorContractOutStockEditAttrUpdateDTO);
                    break;
                case COST_ADJUST:
                    CostAdjustEditAttrUpdateDTO costAdjustEditAttrUpdateDTO = new CostAdjustEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO, costAdjustEditAttrUpdateDTO);
                    costAdjustService.batchEditAttr(costAdjustEditAttrUpdateDTO);
                    break;
                case COMPETITOR:
                    CompetitorEditAttrUpdateDTO competitorEditAttrUpdateDTO = new CompetitorEditAttrUpdateDTO();
                    BeanUtil.copyProperties(formDataUpdateBatchDTO,competitorEditAttrUpdateDTO);
                    competitorService.batchEditAttr(competitorEditAttrUpdateDTO);
                    break;
                default:
                    break;
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("saasUpdateHelp.batchEditAttr 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 批量编辑标签字段,标签字段为数组,特殊处理
     * @param addBatchList
     * @param xbbRefTypeEnum
     * @throws XbbException
     */
    @Transactional(rollbackFor = Exception.class)
    public void batchLabelAttr(AddLabelDTO addLabelDTO, List<PaasFormDataEntityExt> addBatchList, XbbRefTypeEnum xbbRefTypeEnum, Boolean addOrDelete) throws XbbException {
        try {
            String corpid = addLabelDTO.getCorpid();
            Integer saasMark = addLabelDTO.getSaasMark();
            List<Long> idIn = addBatchList.stream().map(item -> item.getId()).collect(Collectors.toList());
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, xbbRefTypeEnum.getCode(), SaasMarkEnum.SAAS.getCode());
            List<PaasFormDataEntityExt> beforePaasFormDataList = paasEsModel.getByIdList(idIn, corpid, saasMark, xbbRefTypeEnum.getCode(), null,indexTypeEnum);

            switch (xbbRefTypeEnum) {
                case CONTRACT:
                    contractService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case CUSTOMER_MANAGEMENT:
                    //评分处理在service里面处理了
                    customerService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case COMPETITOR:
                    competitorService.updateBatchLabelAttr(addLabelDTO,addBatchList,addOrDelete);
                    break;
                case CONTACT:
                    contactService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case PRODUCT:
                    productService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case SUPPLIER:
                    supplierService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case SALES_OPPORTUNITY:
                    opportunityService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case TRANSFER:
                    transferService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case INVENTORY:
                    inventoryService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case OUTSTOCK:
                case CONTRACT_OUTSTOCK:
                case RETURNED_PURCHASE_OUTSTOCK:
                case OTHER_OUTSTOCK:
                case PRODUCTION_MATERIEL_OUTSTOCK:
                case WORK_ORDER_OUTSTOCK:
                    outstockService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case INSTOCK:
                case PURCHASE_INSTOCK:
                case REFUND_INSTOCK:
                case OTHER_INSTOCK:
                case PRODUCTION_INSTOCK:
                case RETURNED_MATERIEL_INSTOCK:
                    instockService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case ASSEMBLE:
                    assembleService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case PAY_PLAN:
                    payPlanService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case PAYMENT:
                    paymentService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case PRODUCTION_ORDER:
                    productionOrderService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case BOM_BILL:
                    bomBillService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case PURCHASE:
                    purchaseService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case RETURNED_PURCHASE:
                    returnedPurchaseService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case INVOICE:
                    invoiceService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case PURCHASE_INVOICE:
                    purchaseInvoiceService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case SUPPLIER_CONTACT:
                    supplierContactService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case WORK_ORDER:
                    workOrderService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case REFUND:
                    refundService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case QUOTATION:
                    quotationService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case PAYMENT_SHEET:
                    paymentSheetService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case PAY_SHEET:
                    payPlanSheetService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case MARKET_ACTIVITY:
                    marketActivityService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case CLUE:
                    clueService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                case WAREHOUSE:
                    warehouseService.updateBatchLabelAttr(addLabelDTO, addBatchList, addOrDelete);
                    break;
                default:
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            // 统一处理打标签移除标签的日志
            operationLogHelp.handleLabelLog( addLabelDTO, idIn, beforePaasFormDataList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("saasUpdateHelp.batchEditAttr 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 精线索释数据释放
     *
     * @param formDataThoroughDeleteDTO 入参
     * @throws XbbException
     */
    private void releaseFineClue(FormDataThoroughDeleteDTO formDataThoroughDeleteDTO) throws XbbException {
        String corpid = formDataThoroughDeleteDTO.getCorpid();
        Integer businessType = formDataThoroughDeleteDTO.getBusinessType();
        List<Long> dataIds = formDataThoroughDeleteDTO.getDataIdList();
        FineClueCompanyEntity fineClueCompanyEntity = fineClueCompanyModel.getByCorpid(corpid, FineClueComboEnum.FINE_CLUE.getCode());
        if (Objects.isNull(fineClueCompanyEntity)) {
            return;
        }
        // 查询精线索数据id
        List<String> pids = fineClueConsumptionModel.getPidsByDataIdIn(corpid, dataIds, businessType, FineClueStatusEnum.UNLOCK.getCode(), ExternalDataSourceEnum.FINE_CLUE.getType());
        if (CollectionsUtil.isEmpty(pids)) {
            return;
        }
        Runnable runnable = () -> {
            try {
                FineClueClueReleaseDTO fineClueClueReleaseDTO = new FineClueClueReleaseDTO();
                BeanUtil.copyProperties(formDataThoroughDeleteDTO, fineClueClueReleaseDTO);
                fineClueClueReleaseDTO.setIds(pids);
                fineClueService.releaseClue(fineClueClueReleaseDTO);
            } catch (XbbException e) {
                LOG.error("releaseClue error",e);
            } catch (Exception e) {
                LOG.error("releaseClue error",e);
            }
        };
        threadPoolBeanConfig.listBatchThreadPool().execute(runnable);
    }
}
